Как разобрать сложный не рабочий SQL Запрос?

Рейтинг: 2Ответов: 2Опубликовано: 15.08.2025

Есть у меня один сложный запрос, он работал до определенного времени, сейчас мне отдали этот запрос, чтоб заработал. у меня вопрос, как от новичка: как вообще разобрать запрос? с чего начинать?

SELECT 
    b.cellName, SUBSTRING(CAST(b.cellName as CHAR),1,6), bt.enbName, ROUND(POWER(10, e.pMAX/100)/1000,0), CAST((CAST(CAST(l.ulChBw AS CHAR) AS INT)/10) AS INT), l.LNCEL, l.earfcnDL, e.phyCellId, l.rootSeqIndex, (
    CASE 
        WHEN CAST(l.prachCS as CHAR) = '14' 
        THEN '35(область)' 
        ELSE '15(город)' 
    END),
    e.tac, (
    CASE 
        WHEN l.dlMimoMode = 0 
        THEN 'SingleTx' 
        ELSE ''
    END)      
FROM 
    config_Nokia4G.LNCEL_begin b
LEFT OUTER JOIN (
    SELECT 
        NetActNo, MRBTS, LNBTS, LNCEL, ulChBw, earfcnDL, rootSeqIndex, prachCS, dlMimoMode 
    FROM config_Nokia4G.LNCEL_FDD 
    UNION 
        SELECT 
            NetActNo, MRBTS, LNBTS, LNCEL, ChBw, earfcn, rootSeqIndex, prachCS, dlMimoMode 
        FROM config_Nokia4G.LNCEL_TDD) l 
ON b.NetActNo = l.NetActNo 
    AND b.MRBTS = l.MRBTS 
    AND b.LNBTS = l.LNBTS 
    AND b.LNCEL = l.LNCEL
LEFT OUTER JOIN config_Nokia4G.LNCEL_end e 
ON b.MRBTS = e.MRBTS 
    AND b.LNBTS = e.LNBTS 
    AND b.LNCEL = e.LNCEL  
LEFT OUTER JOIN config_Nokia4G.LNBTS_begin bt 
ON b.NetActNo = bt.NetActNo 
    AND b.MRBTS = bt.MRBTS 
    AND b.LNBTS = bt.LNBTS
WHERE SUBSTRING(CAST(b.cellName as CHAR),1,2) 
    IN ('IR','KM','MD','SA','AN','BI','HB','IO')
ORDER BY b.MRBTS, b.LNCEL

sql запросы я писал, но простые. такого уровня у меня еще не было.

Ответы

▲ 7

Предлагаю вам такую пошаговую схему отладки. Так вы сможете определить, где конкретно возникает ошибка.

  1. У вас есть два вложенных запроса, проверьте сначала их по отдельности.
SELECT 
    NetActNo, MRBTS, LNBTS, LNCEL, ulChBw, earfcnDL, rootSeqIndex, prachCS, dlMimoMode 
FROM config_Nokia4G.LNCEL_FDD 
SELECT 
    NetActNo, MRBTS, LNBTS, LNCEL, ChBw, earfcn, rootSeqIndex, prachCS, dlMimoMode 
FROM config_Nokia4G.LNCEL_TDD
  1. Затем у вас есть UNION. Проверьте его:
SELECT 
    NetActNo, MRBTS, LNBTS, LNCEL, ulChBw, earfcnDL, rootSeqIndex, prachCS, dlMimoMode 
FROM config_Nokia4G.LNCEL_FDD 
UNION
SELECT 
    NetActNo, MRBTS, LNBTS, LNCEL, ChBw, earfcn, rootSeqIndex, prachCS, dlMimoMode 
FROM config_Nokia4G.LNCEL_TDD
  1. Составьте таблицу, которая получится после выполнения всех JOIN (можно проверять не все сразу, а добавлять по одному).
SELECT *      
FROM 
    config_Nokia4G.LNCEL_begin b
LEFT OUTER JOIN (
    SELECT 
        NetActNo, MRBTS, LNBTS, LNCEL, ulChBw, earfcnDL, rootSeqIndex, prachCS, dlMimoMode 
    FROM config_Nokia4G.LNCEL_FDD 
    UNION 
        SELECT 
            NetActNo, MRBTS, LNBTS, LNCEL, ChBw, earfcn, rootSeqIndex, prachCS, dlMimoMode 
        FROM config_Nokia4G.LNCEL_TDD) l 
ON b.NetActNo = l.NetActNo 
    AND b.MRBTS = l.MRBTS 
    AND b.LNBTS = l.LNBTS 
    AND b.LNCEL = l.LNCEL
LEFT OUTER JOIN config_Nokia4G.LNCEL_end e 
ON b.MRBTS = e.MRBTS 
    AND b.LNBTS = e.LNBTS 
    AND b.LNCEL = e.LNCEL  
LEFT OUTER JOIN config_Nokia4G.LNBTS_begin bt 
ON b.NetActNo = bt.NetActNo 
    AND b.MRBTS = bt.MRBTS 
    AND b.LNBTS = bt.LNBTS
  1. Посмотрите, есть ли в выводе поле b.cellName, соответствует ли оно вашему фильтру Where. Примените фильтр к запросу.
SELECT *  
FROM 
    config_Nokia4G.LNCEL_begin b
LEFT OUTER JOIN (
    SELECT 
        NetActNo, MRBTS, LNBTS, LNCEL, ulChBw, earfcnDL, rootSeqIndex, prachCS, dlMimoMode 
    FROM config_Nokia4G.LNCEL_FDD 
    UNION 
        SELECT 
            NetActNo, MRBTS, LNBTS, LNCEL, ChBw, earfcn, rootSeqIndex, prachCS, dlMimoMode 
        FROM config_Nokia4G.LNCEL_TDD) l 
ON b.NetActNo = l.NetActNo 
    AND b.MRBTS = l.MRBTS 
    AND b.LNBTS = l.LNBTS 
    AND b.LNCEL = l.LNCEL
LEFT OUTER JOIN config_Nokia4G.LNCEL_end e 
ON b.MRBTS = e.MRBTS 
    AND b.LNBTS = e.LNBTS 
    AND b.LNCEL = e.LNCEL  
LEFT OUTER JOIN config_Nokia4G.LNBTS_begin bt 
ON b.NetActNo = bt.NetActNo 
    AND b.MRBTS = bt.MRBTS 
    AND b.LNBTS = bt.LNBTS
WHERE SUBSTRING(CAST(b.cellName as CHAR),1,2) 
    IN ('IR','KM','MD','SA','AN','BI','HB','IO')
ORDER BY b.MRBTS, b.LNCEL
  1. Уберите звёздочку, добавляйте по одному полю в выражение SELECT.
SELECT 
    b.cellName, SUBSTRING(CAST(b.cellName as CHAR),1,6) -- и т.д.    
FROM 
    config_Nokia4G.LNCEL_begin b
LEFT OUTER JOIN (
    SELECT 
        NetActNo, MRBTS, LNBTS, LNCEL, ulChBw, earfcnDL, rootSeqIndex, prachCS, dlMimoMode 
    FROM config_Nokia4G.LNCEL_FDD 
    UNION 
        SELECT 
            NetActNo, MRBTS, LNBTS, LNCEL, ChBw, earfcn, rootSeqIndex, prachCS, dlMimoMode 
        FROM config_Nokia4G.LNCEL_TDD) l 
ON b.NetActNo = l.NetActNo 
    AND b.MRBTS = l.MRBTS 
    AND b.LNBTS = l.LNBTS 
    AND b.LNCEL = l.LNCEL
LEFT OUTER JOIN config_Nokia4G.LNCEL_end e 
ON b.MRBTS = e.MRBTS 
    AND b.LNBTS = e.LNBTS 
    AND b.LNCEL = e.LNCEL  
LEFT OUTER JOIN config_Nokia4G.LNBTS_begin bt 
ON b.NetActNo = bt.NetActNo 
    AND b.MRBTS = bt.MRBTS 
    AND b.LNBTS = bt.LNBTS
WHERE SUBSTRING(CAST(b.cellName as CHAR),1,2) 
    IN ('IR','KM','MD','SA','AN','BI','HB','IO')
ORDER BY b.MRBTS, b.LNCEL
▲ 6

Во-первых нужно определиться, что значит "не работает":

  • Не выдаёт вообще данные?
  • Выдаёт не те данные?
  • Выдаёт ошибку?

Если ошибка - смотреть что за ошибка, где она.
Если нет данных - разбирать запрос по кускам.

В общем виде ваш запрос выглядит так:

SELECT
   -- тут какие-то преобразования вывода
FROM table1
JOIN table2 ON condition2
...
JOIN tableN ON conditionN
WHERE condition1
ORDER BY ...

И ещё у вас там есть подзапрос в первом JOIN.

Что бы делал я:

  • Каждый SELECT (или JOIN, который тоже по сути SELECT) сначала проверяется индивидуально. Просто делаем SELECT скажем десятка записей из таблицы, смотрим, есть ли там вообще записи. WHERE у вас относится к основной таблице, можете сразу для неё SELECT ... WHERE ... сделать. С JOIN ... ON ... сложнее, там обычно условие на связку таблиц, поэтому на этом этапе вы это условие не проверяете
  • Подзапросы тестируются отдельно аналогично (может быть даже в первую очередь)
  • Затем начинаем пристыковывать к нашему SELECT очередной JOIN ON ... по одному и смотреть - есть ли на выходе данные. И так пока все JOIN не пристыкуете
  • Затем уже можно разбираться, что там в выводе первого SELECT-а за преобразования

На очередном этапе будет видно, в какой момент данные перестали поступать на выход, либо выходят какие-то странные. Там и проблема. В вашем случае вроде бы не должно быть особых хитростей, нужно просто уметь видеть общую структуру запроса

P.S. Я смотрел невнимательно, у вас LEFT OUTER JOIN, значит данные на выходе будут всегда, но те колонки, которые будут присоединяться будут содержать NULL-ы, если в присоединяемой таблице нет соответственных данных. Выглядит это странновато, вы должны уточнить, почему так сделано, действительно ли настолько часто бывает, что нет данных в соответствующих таблицах?

Ну и опять же из-за того, что это OUTER JOIN можете сразу все JOIN-ы пристыковывать, разницы наверное не будет, как если их по одному добавлять. Но на будущее эту технику добавления JOIN по одному запомните - пригодится.