Sql Query с уникальным значением столбца - PullRequest
2 голосов
/ 31 марта 2009

Моя цель - написать запрос. У меня есть три таблицы, A, B и C. Таблицы написаны так, что A.bID = B.bID и B.cID = C.cID. Это в основном позволяет мне написать запрос, в котором я связываю запись от a до b и связываю запись b с записью из c. Пока все хорошо, простой запрос.

В чем моя проблема ... один из столбцов, включенных в запрос (назовем его C.col3), должен иметь уникальные значения; значения в этом столбце могут отображаться только один раз в результате запроса, но другие столбцы из других таблиц не имеют этого требования.

Кто-нибудь может мне помочь написать этот запрос?

Спасибо ...

Обновление 1:

Вот макет таблицы (извините, я должен использовать общие имена)

Таблица A
aID, bid, aCol1, aCol2, aCol3 ... aCol10

Таблица B
bid, cid, bCol1, bCol2, bCol3 ... bCol10

Таблица C
cID, cCol1, cCol2, col3 , cCol4 ... cCol10

Без ограничения уникального значения в col3 я написал бы запрос следующим образом:

SELECT
    A.aID, A.bID, A.aCol1 ... A.aCol10,
    B.bID, B.cID, B.bCol1 ... B.bCol10,
    C.cID, C.cCol1, C.cCol2, C.col3 ... C.cCol10
FROM
    A, B, C
WHERE 
    A.bID = B.bID AND B.cID = C.cID

... но, конечно, это не гарантирует, что значения в C.col3 уникальны.

Обновление 2: Подробнее ...
Таблица A и Таблица B имеют отношение один ко многим; A - это «заголовок», B - «элемент».
Таблица B и таблица C имеют отношение один к одному.

Эти таблицы являются частью механизма кэширования, поэтому многие данные выглядят одинаково, но в некоторых столбцах они все же различаются.

Поскольку A является заголовком, большинство дублирующих значений будет найдено в A.

Сначала мне нужно упорядочить строки по A.aID, но затем мне нужно только вернуть первые строки, где значение C.col3 не появляется в предыдущей строке для этого столбца.

Это немного проясняет ситуацию, или я все еще не вижу смысла? :)

Окончательное обновление:

Я выбрал ответ Бартоша Климека, так как он был ближе всего к тому, что мне было нужно; Я просто должен был изменить вложенное предложение соединения в середине.

Спасибо всем за помощь!

Ответы [ 5 ]

3 голосов
/ 31 марта 2009

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

Если у вас есть таблица клиентов [CustomerID, CustomerName] и таблица заказов [OrderID, CustomerID, DollarAmount]

Если вы хотели все заказы для клиентов:

SELECT CustomerName, OrderID, DollarAmount
FROM Customer, Orders
WHERE Customer.CustomerID = Orders.CustomerID

вернется

 "Acme Corp.", 1, $2300
 "Acme Corp.", 2, $3022
 "A company",  3, $1234

Все хорошо.

Но эквивалент вашего вопроса задает этот запрос, но с уникальными CustomerNames. Что бы вы отобразили для OrderID и DollarAmount рядом с «Acme Corp»?

Вы можете использовать агрегаты для отображения чего-либо,

SELECT CustomerName, MAX(OrderID), SUM(DollarAmount)
FROM Customer, Orders
WHERE Customer.CustomerID = Orders.CustomerID
GROUP BY Orders.CustomerID

Но я полагаю, что вы упомянули, что не хотите использовать агрегаты.

Это ясно объясняет проблему?

2 голосов
/ 31 марта 2009

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

Таблица A

BID COL1
1   Value1
2   Value1
3   Value2

Таблица B

BID CID COL 2
1   4   ValueX
2   5   ValueY
3   6   ValueZ

Таблица C

CID COL3
4   Value#
5   Value@
6   Value~

Ожидаемый результат

A.Col1   A.BID B.BID B.CID B.COL2 C.CID C.COL3
Value1?? 1     1     4     ValueX 4     Value#
Value1?? 2     1     5     ValueY 5     Value@ 
Value2   3     3     6     ValyeZ 6     Value~

По вопросу, который вы не хотите, чтобы значение1 повторялось в первом столбце, но что вы предлагаете, входит во второй ряд, где оно обычно повторяется, если у вас не было уникального ограничения?

1 голос
/ 31 марта 2009
SELECT A.*, B.*, C.*
  FROM C
    JOIN B ON B.cID = C.cID
    JOIN A ON A.bID = B.bID
    JOIN
    (
      SELECT id = min(aID)
        FROM C
          JOIN B ON B.cID = C.cID
          JOIN A ON A.bID = B.bID
        GROUP BY col3
    ) D ON D.id = A.aID

Обратите внимание, что подзапрос в конце гарантирует, что для каждого значения col3 у вас будет не более одной записи в конечном наборе результатов. Выбранная запись - это запись с минимальным идентификатором. Очевидно, я предполагаю, что aID, bID и cID являются первичными ключами A, B и C соответственно.

0 голосов
/ 31 марта 2009

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

select max(a.col1), sum(b.col2), col3 from a, b, c
where A.bID = B.bID, and B.cID = C.cID
group by C.col3

Для всех столбцов, которые не сгруппированы, необходимо использовать агрегатные функции, например

  • AVG: среднее по столбцу.
  • COUNT: Количество записей.
  • MAX: максимум столбца.
  • MIN: минимум столбца.
  • СУММА: Сумма столбца.
0 голосов
/ 31 марта 2009
select distinct c.col3 from c inner join b on c.cID = b.cID inner join a on b.bID = a.bID
...