ВИБІРТЕ ДИСТИНЦТУ в одному стовпці, а повертаючи інші стовпці?


12

У мене є запит, який використовує три таблиці пошуку, щоб отримати всю необхідну мені інформацію. Мені потрібно мати DISTINCTзначення для одного стовпця, однак мені також потрібні решта даних, пов'язаних з ним.

Мій SQL-код:

SELECT acss_lookup.ID AS acss_lookupID,
   acss_lookup.product_lookupID AS acssproduct_lookupID,
   acss_lookup.region_lookupID AS acssregion_lookupID,
   acss_lookup.document_lookupID AS acssdocument_lookupID,
   product.ID AS product_ID,
   product.parent_productID AS productparent_product_ID,
   product.label AS product_label,
   product.displayheading AS product_displayheading,
   product.displayorder AS product_displayorder,
   product.display AS product_display,
   product.ignorenewupdate AS product_ignorenewupdate,
   product.directlink AS product_directlink,
   product.directlinkURL AS product_directlinkURL,
   product.shortdescription AS product_shortdescription,
   product.logo AS product_logo,
   product.thumbnail AS product_thumbnail,
   product.content AS product_content,
   product.pdf AS product_pdf,
   product.language_lookupID AS product_language_lookupID,
   document.ID AS document_ID,
   document.shortdescription AS document_shortdescription,
   document.language_lookupID AS document_language_lookupID,
   document.document_note AS document_document_note,
   document.displayheading AS document_displayheading
FROM acss_lookup
     INNER JOIN product ON (acss_lookup.product_lookupID = product.ID)
     INNER JOIN document ON (acss_lookup.document_lookupID = document.ID)
ORDER BY product_displayheading ASC;

Я хочу отримати всі продукти з цього запиту, але я хочу отримати їх лише один раз, оскільки я заповнююю спадне меню для пошукової програми. Я хочу, щоб користувач міг вибрати з продуктів, що знаходяться в цій таблиці (тому мені вони потрібні лише один раз).

Це занадто складно? Чи варто використовувати більш спрощений підхід?


Але продукт пов'язаний з багатьма документами. І ваш запит повертає їх усі (документи на товар). Яку вибрати?
ypercubeᵀᴹ

Відповіді:


7

Ще один підхід, про який ще не було сказано, - це використання віконних функцій, наприклад row_number:

   SELECT * FROM  
   (
   SELECT acss_lookup.ID AS acss_lookupID, 
   ROW_NUMBER() OVER 
   (PARTITION BY your_distinct_column ORDER BY any_column_you_think_is_appropriate)
   as num,
   acss_lookup.product_lookupID AS acssproduct_lookupID,
   acss_lookup.region_lookupID AS acssregion_lookupID,
   acss_lookup.document_lookupID AS acssdocument_lookupID,
   product.ID AS product_ID,
   product.parent_productID AS productparent_product_ID,
   product.label AS product_label,
   product.displayheading AS product_displayheading,
   product.displayorder AS product_displayorder,
   product.display AS product_display,
   product.ignorenewupdate AS product_ignorenewupdate,
   product.directlink AS product_directlink,
   product.directlinkURL AS product_directlinkURL,
   product.shortdescription AS product_shortdescription,
   product.logo AS product_logo,
   product.thumbnail AS product_thumbnail,
   product.content AS product_content,
   product.pdf AS product_pdf,
   product.language_lookupID AS product_language_lookupID,
   document.ID AS document_ID,
   document.shortdescription AS document_shortdescription,
   document.language_lookupID AS document_language_lookupID,
   document.document_note AS document_document_note,
   document.displayheading AS document_displayheading
   FROM acss_lookup
     INNER JOIN product ON (acss_lookup.product_lookupID = product.ID)
     INNER JOIN document ON (acss_lookup.document_lookupID = document.ID)
   )a
   WHERE a.num = 1
   ORDER BY product_displayheading ASC;

@ a1ex07- Дякую! Це спрацювало. Кожен раз, коли я намагався адаптувати якийсь приклад з мережі, саме мене приєднували, що мене збентежили, але я думаю, що зараз це розумію.
stephmoreland

Було б краще робити приєднання поза підзапитом, якщо не те, що робить дані "виразними", щоб мінімізувати дані, які ви запитуєте, і дублювати лише для "викидання", вибравши num = 1 з віконної функції.
Allan S. Hansen

4

Є кілька способів зробити це. Два основних, які я використовую, є загальними табличними виразами та підзапитами. Використовуючи CTE, ваш запит виглядатиме приблизно так:

WITH theResultSet AS
(
    SELECT DISTINCT(column) AS col1 FROM some.table
)
SELECT whatever
  FROM more.data AS a
  JOIN theResultSet as b ON a.col1 = b.col1
  /* additional joins, clauses etc...*/

Або за допомогою підпиту:

SELECT whatever
  FROM more.data AS a
  JOIN (SELECT DISTINCT(column) AS col1 FROM some.table) AS b ON a.col1 = b.col1
/* additional joins, clauses etc... */

Я зазвичай тестую, щоб побачити, що швидше, і піти з цим.

Я сподіваюся, що це вам допоможе.


Я думав, що я зрозумів вашу відповідь, тому я спробував це (перший), але я думаю, що мої ПРИЄДНАННЯ викликають проблему з приєднанням вашого рішення.
stephmoreland

що таке стовпець, який потрібно розрізнити? Я опублікую більш комплексне рішення для вас.
Містер Броунстоун

product.displayheading the column
stephmoreland

1

(Я думаю, що ви намагаєтеся зробити це "згорнути" кожен рядок результатів на один продукт, тому ця відповідь триває це припущення.)

Це неможливо. Щоб отримати відповідні дані 1 .. * з інших таблиць, ви повинні повернути повторювані значення в інших стовпцях.

Як правило, спосіб вирішити це - запустити запит таким, який він є, та обробити об'єднаний результат, встановлений у коді програми. Я зазвичай роблю це, використовуючи хеш-колекційний підхід, який в кінцевому підсумку складається з різних об'єктів кожного типу в колекції на основі ключового значення.

Хоча цей підхід коштує дорожче з точки зору мережевого трафіку, зазвичай краще робити щось на зразок запуску декількох запитів і зшивання результатів, як вам потрібно, в коді програми. Це залежить від багатьох факторів, у тому числі від того, як часто виконується запит / запити та скільки повертається даних.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.