Общие вопросы SQL - PullRequest
       5

Общие вопросы SQL

0 голосов
/ 24 января 2009

У меня есть стол A

ID    Term
10    A
10    B
10    C
20    A
20    B
20    E

как лучше написать SQL на

  • получить ID 10, если я попытаюсь найти (A, B, C)
  • НИЧЕГО не получите, если я попытаюсь найти (A, B)
  • получить ID 20, если я попытаюсь найти НЕ в (C, D)

.

Select distinct ID from TableA where Term in (A,B,C) will return both 10 and 20

Select distinct ID from TableA where Term in (A,B) will also return both 10 and 20

Select distinct ID from TableA where Term NOT in (C,D) will also return both 10 and 20

Спасибо!

Ответы [ 4 ]

6 голосов
/ 24 января 2009

1.

SELECT ID 
FROM TableA
WHERE Term IN ('A','B','C')
GROUP BY ID
HAVING COUNT(ID)=3
LIMIT 1

Здесь 3 будет длина набора (A, B, C в данном случае). 2 и 3, вероятно, могут быть некоторым изменением вышеупомянутого.

2 голосов
/ 24 января 2009

Я предполагаю, что вам нужна одна форма запроса, которую можно использовать для ответа на все три вопроса, а не разные типы запросов для каждого вопроса.

В этих решениях используется COUNT(), не считая NULL с. Когда OUTER JOIN не соответствует строке в t2, это приводит к NULL для всех столбцов из t2.

получить ID 10, если я попытаюсь найти (A, B, C)

ID 10 имеет три различных значения термина, и мы ищем все три.

SELECT t1.ID
FROM TableA t1 LEFT OUTER JOIN TableA t2 
  ON (t1.ID = t2.ID AND t1.term = t2.term AND t2.term IN ('A', 'B', 'C'))
GROUP BY t1.ID
HAVING COUNT(t1.term) = COUNT(t2.term);

НИЧЕГО не получите, если я попытаюсь найти (A, B)

И ID 10, и ID 20 имеют три разных значения термина, но наш поиск только для двух. Количество равно 3 = 2 для обоих идентификаторов, поэтому ни один из них не имеет равного числа.

SELECT t1.ID
FROM TableA t1 LEFT OUTER JOIN TableA t2 
  ON (t1.ID = t2.ID AND t1.term = t2.term AND t2.term IN ('A', 'B'))
GROUP BY t1.ID
HAVING COUNT(t1.term) = COUNT(t2.term);

получить ID 20, если я попытаюсь найти НЕ в (C, D)

ID 20 имеет три различных значения термина, и все три из них НЕ являются «C» или «D». Таким образом, количество равно.

SELECT t1.ID
FROM TableA t1 LEFT OUTER JOIN TableA t2 
  ON (t1.ID = t2.ID AND t1.term = t2.term AND t2.term NOT IN ('C', 'D'))
GROUP BY t1.ID
HAVING COUNT(t1.term) = COUNT(t2.term);
0 голосов
/ 24 января 2009
CREATE TABLE mySearch (
    search_id       INT,
    val             CHAR(1),
    is_required     INT,
    is_excluded     INT
    )  

INSERT INTO mySearch VALUES (1, 'A', 1, 0)   -- Search1 : A is required  
INSERT INTO mySearch VALUES (1, 'B', 1, 0)   -- Search1 : B is required  
INSERT INTO mySearch VALUES (1, 'C', 1, 0)   -- Search1 : C is required  

INSERT INTO mySearch VALUES (2, 'A', 1, 0)   -- Search2 : A is required  
INSERT INTO mySearch VALUES (2, 'B', 1, 0)   -- Search2 : B is required  

INSERT INTO mySearch VALUES (3, 'C', 0, 1)   -- Search3 : C is excluded
INSERT INTO mySearch VALUES (3, 'D', 0, 1)   -- Search3 : D is excluded  

SELECT
    [search].search_id,
    [data].id
FROM
    TableA            AS [data]
LEFT JOIN
    my_search         AS [search]
        ON [search].val = [data].Term
GROUP BY
    [search].search_id,
    [data].ID
HAVING
    ISNULL(SUM([search].is_included),0) = (SELECT SUM(is_included) FROM mySearch WHERE search_id = [search].search_id)
    AND MAX([search].is_excluded) IS NULL

Должен удовлетворять всем трем поискам в одном запросе. К сожалению, я не могу проверить это, потому что я нахожусь в доме адвокатов, и у них нет игрушек-гиков для тестирования;)

0 голосов
/ 24 января 2009

Q1

SQLite version 3.6.10
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> create table A(ID smallint, term varchar(1));
sqlite> insert into A values(10, 'A');
sqlite> insert into A values(10, 'B');
sqlite> insert into A values(10, 'C');
sqlite> insert into A values(20, 'A');
sqlite> insert into A values(20, 'B');
sqlite> insert into A values(20, 'E');
sqlite> SELECT ID FROM A WHERE TERM = 'A' INTERSECT SELECT ID FROM A WHERE TERM
= 'B' INTERSECT SELECT ID FROM A WHERE TERM = 'C';
10

Q2

sqlite> SELECT ID FROM A WHERE TERM = 'A' EXCEPT SELECT ID FROM A WHERE TERM = '
B';

не возвращает результатов. ИСКЛЮЧЕНИЕ может также называться МИНУС в некоторых версиях SQL

Q3

sqlite> SELECT ID FROM A EXCEPT SELECT ID FROM A WHERE TERM = 'C' UNION SELECT I
D FROM A WHERE TERM = 'D';
20
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...