Сложный оператор SQL нуждается в улучшении - PullRequest
0 голосов
/ 05 октября 2019

Задав вопрос в другом потоке о том, почему мой сложный оператор SQL не работает (в основном получаются странные сообщения "кортежей"), я был впечатлен, что мой синтаксис SQL был паршивым. Я с готовностью принимаю это, поскольку я относительно новичок в сложных вещах SQL, поэтому я надеюсь, что те из вас, кто знает лучше меня (я полагаю, большинство из вас), могут мне помочь.

Вотобщая вещь, необходимая:Это из системы управления недвижимостью, которая (не помогает мне Бог) имеет столбцы идентификаторов, но вместо этого использует комбинацию «dept_no» (свойство) и «единица измерения». В одной таблице находится столбец rent_amoun (странные имена полей, так как они были ранее увеличены по сравнению с Visual FoxPro, который допускал только 10 имен полей символов).

Затем есть таблица trans (транзакции), которая имееткаждый тип транзакции, совершаемой каждым в каждом объекте недвижимости. Из этой таблицы мне нужно найти записи «Срок оплаты» для каждой комбинации dept_no / unit (в порядке убывания даты) и найти первую запись, которая МЕНЬШЕ, чем сумма аренды, в первой таблице.

Iзатем нужно взять содержимое «amt_charge» и «transcti2» (транзакция_дата) из таблицы trans и вставить эти значения в столбцы «oldrent» и «idate» третьей таблицы (rentinc). Поэтому я понимаю, что приведенный ниже оператор SQL является дилетантским, но на самом деле он работал в окне запросов SSMS, но доставил мне много проблем с ошибками odbc_connect () («tuples» без «SQL_CUR_USE_ODBC» в строке подключения и «Неоднозначный amt_charge» сэто).

Вот звонок:

SELECT x.dept_no,
       x.unit,
       x.amt_charge,
       q.rent_amoun,
       CONVERT(DATE, x.transacti2, 101) AS transacti2 
FROM (SELECT TOP (100) PERCENT
             t.dept_no,
             t.unit,
             t.amt_charge,
             l.rent_amoun 
      FROM (SELECT TOP (100) PERCENT
                   w.dept_no,
                   w.unit,
                   w.amt_charge 
            FROM trans w 
            WHERE (transacti3 = 'Rent Due') 
            GROUP BY w.dept_no,
                     w.unit,
                     w.amt_charge 
            ORDER BY w.dept_no,
                     w.unit,
                     w.amt_charge
           ) AS t 
           INNER JOIN lease_unit AS l ON t.dept_no = l.dept_no
                                AND t.unit = l.unit 
      ORDER BY t.dept_no,
               t.unit,
               t.amt_charge DESC
      ) AS q 
      INNER JOIN trans AS x ON x.dept_no = q.dept_no
                           AND x.unit = q.unit 
WHERE x.amt_charge IS NOT NULL
  AND x.transacti3 = 'Rent Due'
ORDER BY x.dept_no,
         x.unit,
         x.transacti2 DESC;

1 Ответ

0 голосов
/ 05 октября 2019

Это не ответ, а комментарий, который не помещается в разделе комментариев.

Если у вас есть подзапросы, включенные в подзапросы, я бы посоветовал перефразировать весь запрос, используяCTE (общие табличные выражения). Например, ваш запрос может выглядеть следующим образом:

WITH
t as (
  SELECT TOP (100) PERCENT
    w.dept_no, 
    w.unit, 
    w.amt_charge 
  FROM trans w 
  WHERE (transacti3 = 'Rent Due') 
  GROUP BY w.dept_no, w.unit, w.amt_charge 
  ORDER BY w.dept_no, w.unit, w.amt_charge
),
q as (
  SELECT TOP (100) PERCENT
    t.dept_no,
    t.unit,
    t.amt_charge,
    l.rent_amoun 
  FROM t 
  INNER JOIN lease_unit AS l ON t.dept_no = l.dept_no AND t.unit = l.unit 
  ORDER BY t.dept_no, t.unit, t.amt_charge DESC
)
SELECT x.dept_no,
       x.unit,
       x.amt_charge,
       q.rent_amoun,
       CONVERT(DATE, x.transacti2, 101) AS transacti2 
FROM q 
INNER JOIN trans AS x ON x.dept_no = q.dept_no AND x.unit = q.unit 
WHERE x.amt_charge IS NOT NULL
  AND x.transacti3 = 'Rent Due'
ORDER BY x.dept_no, x.unit, x.transacti2 DESC

Таким образом, вы можете сначала проверить подзапросы, чтобы убедиться, что они работают правильно. Например, чтобы проверить q:

WITH
t as (
  SELECT TOP (100) PERCENT
    w.dept_no, 
    w.unit, 
    w.amt_charge 
  FROM trans w 
  WHERE (transacti3 = 'Rent Due') 
  GROUP BY w.dept_no, w.unit, w.amt_charge 
  ORDER BY w.dept_no, w.unit, w.amt_charge
),
q as (
  SELECT TOP (100) PERCENT
    t.dept_no,
    t.unit,
    t.amt_charge,
    l.rent_amoun 
  FROM t 
  INNER JOIN lease_unit AS l ON t.dept_no = l.dept_no AND t.unit = l.unit 
  ORDER BY t.dept_no, t.unit, t.amt_charge DESC
)
select * from q -- this line queries q. Or you can check t here...

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...