Как объединить две таблицы с отношением один ко многим - PullRequest
0 голосов
/ 08 января 2019

У меня есть две таблицы основных заказов и заказанных продуктов.

Table 1: ORDERS
"CREATE TABLE IF NOT EXISTS ORDERS("
                       "id_order INTEGER PRIMARY KEY AUTOINCREMENT,
                       "o_date TEXT,"
                       "o_seller TEXT,"
                       "o_buyer TEXT,"
                       "o_shipping INTEGER,"
                       "d_amount INTEGER,"
                       "d_comm INTEGER,"
                       "d_netAmount INTEGER)"
Table 2: ORDERED_PRODUCTS
"CREATE TABLE IF NOT EXISTS dispatch_products("
                       "id_order INTEGER NOT NULL REFERENCES ORDERS(id_order),"
                       "product_name INTEGER,"
                       "quantity INTEGER,"
                       "rate INTEGER)"

Я попытался объединить эти две таблицы, используя следующий запрос:

SELECT *
FROM ORDERS a
INNER JOIN ORDERED_PRODUCTS b
ON a.id_order = b.id_order
WHERE a.buyer = 'abc'

Проблема связана с записями с несколькими продуктами в таблице 2. Вывод, который я получаю, выглядит следующим образом:

order_ID date seller buyer Ship   amt  comm nAmt Prod  Qty Rate
1             A      x       5    100  5    115  Scale 10  10
2             B      abc     10   100  5    115  pen    5  10
2             B      abc     10   100  5    115  paper 10   5
3             C      xyz     10   100  5    220  book   5  20
3             C      xyz     10   100  5    220  stapl 10  10

expected output:
order_ID date seller buyer Ship   amt  comm nAmt Prod  Qty Rate
1             A      x       5    100  5    115  Scale 10  10
2             B      abc     10   100  5    115  pen    5  10
                                                 Paper 10   5
3             C      xyz     10   100  5    220  Book   5  20
                                                 Stapl 10  10

Ответы [ 2 ]

0 голосов
/ 08 января 2019

Вот способ заставить БД делать это, но вам понадобится версия SQLite, которая поддерживает оконные функции (3.10 нет), или другая БД (SQLS> 2008, Oracle> 9 или другая громкая БД с большим именем). за последние 10 лет или около того (MySQL):

SELECT 
  CASE WHEN rn = 1 THEN d.o_date END as o_date,
  CASE WHEN rn = 1 THEN d.o_seller END as o_seller,
  CASE WHEN rn = 1 THEN d.o_buyer END as o_buyer,
  CASE WHEN rn = 1 THEN d.o_shipping END as o_shipping,
  CASE WHEN rn = 1 THEN d.d_amount END as d_amount,
  CASE WHEN rn = 1 THEN d.d_comm END as d_comm,
  CASE WHEN rn = 1 THEN d.d_netAmount END as d_netAmount,
  d.name,
  d.qty,
  d.rate
FROM
  SELECT o.*, op.name, op.qty, op.rate, row_number() over(partition by o.id_order order by op.name, op.qty, op.rate) rn
  FROM ORDERS o
  INNER JOIN ORDERED_PRODUCTS op
  ON o.id_order = op.id_order
  WHERE o.buyer = 'abc'
) d
ORDER BY d.id_order, d.rn

Мы в основном принимаем ваш запрос, добавляем номер строки, который перезапускается при каждом изменении идентификатора заказа, и показываем только данные из таблицы заказов, где число равно 1. Если ваш SQLite не имеет номера строки, вы можете подделать его: Как использовать ROW_NUMBER в sqlite , который я оставлю в качестве упражнения для читателя:)

0 голосов
/ 08 января 2019

Базы данных на самом деле не работают так; Вы получили то, что просили, и без дубликатов (все строки разные). Вы смотрите на столбцы данных, поступивших из заказов, и говорите: «О, данные дублированы», но это не так - они объединены «в контексте»

Представьте, что я дал вам только одну из ваших строк выборки из ожидаемого результата:

                                             Paper 10   5

Обещаю, я просто скопировал и вставил это.

Из какого он заказа?

Понятия не имею ... Вы потеряли контекст, поэтому он может быть из любого заказа. Строки - это отдельные объекты, которые стоят отдельно и без ссылки на любую другую строку как набор данных. Вот почему одинаковая информация о заказе должна появляться в каждой строке. Можно было бы создать базу данных для получения ожидаемого результата, который вы запрашивали, но это было бы действительно сложно в простой базе данных, такой как sqlite. Для меня важнее указать, почему существует разница между тем, что, по вашему мнению, даст вам запрос, и тем, что оно дало вам, поскольку я думаю, что это реальная проблема: запрос дал вам то, что предполагалось, в этом нет ошибки Это; это скорее ошибочное предположение о том, что вы получите

Если вы пытаетесь подготовить отчет, в котором в качестве заголовка используется порядок, выберите их по отдельности в приложении переднего плана. Выберите ВСЕ заказы, затем один за другим (заказ за заказом) извлеките все детали товара, создав отчет по ходу дела:

myorders = dbquery("SELECT * FROM ORDERS")
for each(order o in myorders)
  print(o.header)
  details = dbquery("SELECT * FROM dispatch_products where id_order = ?", o.id)
  for each(detail d in details)
    print(d.prod, d.qty, d.rate)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...