SQL в строке эквивалентно пересечению - PullRequest
2 голосов
/ 13 апреля 2011

Есть ли встроенная команда sql, которая похожа или дает те же результаты, что и intersect?Если нет, то есть ли способ переписать запрос, чтобы он был в одном запросе, вместо использования intersect?

Мой текущий запрос sql:

SELECT 
  c.Log_Link 
FROM 
  Classes c INNER JOIN 
  ClassValues cv ON c.Class_Link = cv.Class_Link INNER JOIN 
  ClassSelection cs ON cv.ClassSelection_Link = cs.ClassSelection_Link
WHERE 
  cs.classselection_link IN (95,1)

Но что я на самом делепосле:

SELECT 
  c.Log_Link 
FROM 
  Classes c INNER JOIN 
  ClassValues cv ON c.Class_Link = cv.Class_Link INNER JOIN 
  ClassSelection cs ON cv.ClassSelection_Link = cs.ClassSelection_Link
WHERE 
  cs.classselection_link = 95 
INTERSECT 
SELECT 
  c.Log_Link 
FROM 
  Classes c INNER JOIN 
  ClassValues cv ON c.Class_Link = cv.Class_Link INNER JOIN 
  ClassSelection cs ON cv.ClassSelection_Link = cs.ClassSelection_Link
WHERE 
  cs.classselection_link = 1

Спасибо

Ответы [ 4 ]

2 голосов
/ 13 апреля 2011

INTERSECT и EXISTS семантически одинаковы.И вам не нужно так много таблиц

SELECT 
  c.Log_Link 
FROM 
  Classes c
WHERE 
  EXISTS (
      SELECT * FROM ClassValues cv
      WHERE c.Class_Link = cv.Class_Link AND cv.classselection_link = 95)
AND
  EXISTS (
      SELECT * FROM ClassValues cv
      WHERE c.Class_Link = cv.Class_Link AND cv.classselection_link = 1)
2 голосов
/ 13 апреля 2011

Возможно, используется внутреннее соединение ...

SELECT
    *
FROM
    (
        SELECT 
          c.Log_Link 
        FROM 
          Classes c INNER JOIN 
          ClassValues cv ON c.Class_Link = cv.Class_Link INNER JOIN 
          ClassSelection cs ON cv.ClassSelection_Link = cs.ClassSelection_Link
        WHERE 
          cs.classselection_link = 95 
    ) T1
INNER JOIN
    (
        SELECT 
          c.Log_Link 
        FROM 
          Classes c INNER JOIN 
          ClassValues cv ON c.Class_Link = cv.Class_Link INNER JOIN 
          ClassSelection cs ON cv.ClassSelection_Link = cs.ClassSelection_Link
        WHERE 
          cs.classselection_link = 1
    ) T2
ON
    T1.Log_Link = T2.Log_Link
2 голосов
/ 13 апреля 2011

Вы всегда можете сделать:

SELECT DISTINCT
  c.Log_Link 
FROM 
  Classes c INNER JOIN 
  ClassValues cv1 ON c.Class_Link = cv1.Class_Link INNER JOIN 
  ClassSelection cs1 ON cv1.ClassSelection_Link = cs1.ClassSelection_Link

INNER JOIN
  ClassValues cv2 ON c.Class_Link = cv2.Class_Link INNER JOIN 
  ClassSelection cs2 ON cv2.ClassSelection_Link = cs2.ClassSelection_Link

WHERE 
    cs1.classselection_link = 95 
  AND
    cs2.classselection_link = 1

или с GROUP BY :

SELECT 
  c.Log_Link 
FROM 
  Classes c INNER JOIN 
  ClassValues cv ON c.Class_Link = cv.Class_Link INNER JOIN 
  ClassSelection cs ON cv.ClassSelection_Link = cs.ClassSelection_Link
WHERE 
  cs.classselection_link IN (95,1)
GROUP BY
  c.Class_Link
HAVING
  COUNT(c.Class_Link) = 2

, и так как вам действительно не нужна таблица ClassSelection:

SELECT 
  c.Log_Link 
FROM 
  Classes c INNER JOIN 
  ClassValues cv ON c.Class_Link = cv.Class_Link
WHERE 
  cv.ClassSelection_Link IN (95,1)
GROUP BY
  c.Class_Link
HAVING
  COUNT(c.Class_Link) = 2

Как указал gbn, я предположил, что (Class_Link, ClassSelection_Link) равно UNIQUE в таблице ClassValues.

Если это не так, то предложение HAVING в последних 2запросы должны быть изменены на:

HAVING
  COUNT(DISTINCT cv.ClassSelection_Link) = 2
1 голос
/ 13 апреля 2011

Я почти уверен, что вы просто хотите отличиться.Вы пытаетесь получить уникальный набор c.Log_Link, который соответствует любому критерию, правильно?Если это так:

SELECT DISTINCT
  c.Log_Link 
FROM 
  Classes c INNER JOIN 
  ClassValues cv ON c.Class_Link = cv.Class_Link INNER JOIN 
  ClassSelection cs ON cv.ClassSelection_Link = cs.ClassSelection_Link
WHERE 
  cs.classselection_link IN (95,1)

Редактировать: я вижу ваши разъяснения.Я думаю, что объединение производных таблиц, как предположил amit_g, было бы правильным способом.

Хотя я бы немного подправил:

SELECT 
  c.Log_Link 
FROM 
  Classes c INNER JOIN 
  ClassValues cv ON c.Class_Link = cv.Class_Link INNER JOIN 
  ClassSelection cs ON cv.ClassSelection_Link = cs.ClassSelection_Link
  INNER JOIN (
        SELECT 
          c.Log_Link 
        FROM 
          Classes c INNER JOIN 
          ClassValues cv ON c.Class_Link = cv.Class_Link INNER JOIN 
          ClassSelection cs ON cv.ClassSelection_Link = cs.ClassSelection_Link
        WHERE 
          cs.classselection_link = 1
    ) T2 ON c.Log_Link = T2.Log_Link
WHERE 
  cs.classselection_link = 95 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...