Member 13779417 Ответов: 2

Добавление условия с помощью EXISTS со вторым внутренним соединением


Следующая хранимая процедура работает нормально, но мне нужно добавить еще одно условие по отношению к другой таблице под названием tblItems. Я требую, чтобы tblAccounts.accountID присоединился к tblItems.AccountID, чтобы я мог проверить, есть ли tblItems.fileID > 0 для каждого accountID с @bootsaledate, и если да, то верните результаты для кода ниже..

SELECT *,
CASE WHEN RowNo < cnt THEN 'N' ELSE 'Y' END AS lastbox
FROM
(
SELECT ROW_NUMBER() OVER (ORDER BY dateAdded desc) as [RowNo],
COUNT(*) OVER () cnt,
tblAccounts.skypeUserName, tblAccounts.contactName, tblorders.friendlyOrderID
FROM tblOrders
INNER JOIN tblAccounts ON tblOrders.accountID=tblAccounts.accountID
WHERE bootSaleDate = @bootSaleDate AND orderStatus='Completed'
) t
WHERE RowNo BETWEEN (@page*8)-7 AND (@page*8)


Что я уже пробовал:

Я попробовал следующее, Но похоже, что он возвращает результат строки для каждого появления fileID в tblItems..

SELECT *,
CASE WHEN RowNo < cnt THEN 'N' ELSE 'Y' END AS lastbox
FROM
(
SELECT ROW_NUMBER() OVER (ORDER BY orderDate desc) as [RowNo],
COUNT(*) OVER () cnt,
tblAccounts.skypeUserName, tblAccounts.contactName, tblorders.friendlyOrderID
FROM tblOrders
INNER JOIN tblAccounts ON tblOrders.accountID=tblAccounts.accountID
INNER JOIN tblItems ON tblOrders.accountID=tblItems.accountID
WHERE EXISTS(select 1 from tblItems WHERE tblItems.fileID > 0 AND tblItems.accountID = tblOrders.accountID AND tblOrders.bootSaleDate = @bootSaleDate)  AND tblOrders.bootSaleDate = @bootSaleDate AND tblOrders.orderStatus='Completed' 
) t
WHERE RowNo BETWEEN (@page*8)-7 AND (@page*8)

2 Ответов

Рейтинг:
2

Eek Ten Bears

Это скорее комментарий и предложение, чем решение

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

AND tblOrders.bootSaleDate = @bootSaleDate
что в значительной степени ничего не делает. Это говорит о том, что вы позволили ему дрейфовать с того места, где он должен быть. Я действительно тестировал ваш код и не понимаю, что вы видите, но ваши данные могут включать факторы, которых нет в моем тесте. EXISTS возвращает TRUE, как только он находит что-то, но это включает в себя нулевую запись (в отличие от no-records), так что если ваши данные вызывают null, возвращаемый подзапросом, то это может объяснить это. Независимо от того, что я предполагаю, я бы не стал тратить время на выяснение того, что было неправильно, вместо этого я бы рекомендовал вам сначала продолжить, удалив ненужную сложность, и есть гораздо более простой метод, который сразу же доступен.

Снять где существует полностью, а просто добавить и предложении tblItems внутреннее соединение так
SELECT *,
CASE WHEN RowNo < cnt THEN 'N' ELSE 'Y' END AS lastbox
FROM
(
  SELECT ROW_NUMBER() OVER (ORDER BY orderDate desc) as [RowNo],
  COUNT(*) OVER () cnt,
  tblAccounts.skypeUserName, tblAccounts.contactName, tblorders.friendlyOrderID
  FROM tblOrders
  INNER JOIN tblAccounts 
  ON tblOrders.accountID=tblAccounts.accountID
  INNER JOIN tblItems 
  ON tblOrders.accountID=tblItems.accountID AND tblItems.fileID > 0
  WHERE 
    tblOrders.bootSaleDate = @bootSaleDate 
    AND tblOrders.orderStatus='Completed' 
) t
WHERE RowNo BETWEEN (@page*8)-7 AND (@page*8)


Более чистый.


Member 13779417

Спасибо за ответ. Однако я получаю тот же результат с вашим кодом.. несколько строк одного и того же accountID, skypeUserName, contactName, friendlyOrderID. Похоже, что он выбирает строку для каждого появления fileID, существующего в tblitems для этого accountid и даты. Что мне нужно, так это просто выбрать информацию один раз для каждого accountID независимо от того, как могут существовать события fileID на эту дату, просто до тех пор, пока они существуют.

Рейтинг:
0

Eek Ten Bears

ну ладно, теперь я понимаю, чего ты добиваешься. Древесина для проблемы деревьев. Вам вообще не нужно много делать, чтобы ваш код работал.

Я все еще не очень люблю использовать EXISTS но это может быть уместно здесь и будет работать если вы удалите это:

INNER JOIN tblItems ON tblOrders.accountID=tblItems.accountID 
Вы не используете его ни для чего, кроме как для того, чтобы дать вам несколько строк вместо всего лишь 1 (это должно быть смешно-извините). На предложение присоединиться вторит where в вашем существовании.

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

SELECT *,
CASE WHEN RowNo < cnt THEN 'N' ELSE 'Y' END AS lastbox
FROM
(
SELECT ROW_NUMBER() OVER (ORDER BY orderDate desc) as [RowNo],
COUNT(*) OVER () cnt,
tblAccounts.skypeUserName, tblAccounts.contactName, tblorders.friendlyOrderID
FROM tblOrders
INNER JOIN tblAccounts ON tblOrders.accountID=tblAccounts.accountID
WHERE EXISTS(select 1 from tblItems WHERE tblItems.fileID > 0 AND tblItems.accountID = tblOrders.accountID)  
AND 
tblOrders.bootSaleDate = @bootSaleDate AND tblOrders.orderStatus='Completed' 
) t
WHERE RowNo BETWEEN (@page*8)-7 AND (@page*8)