Выберите первую подходящую строку
У меня есть таблица "tbl", которая выглядит так:
prod | cust | qty
p1 | c1 | 5
p1 | c2 | 10
p2 | c1 | 2
p3 | c2 | 8
Мне нужен отдельный список пар продуктов и клиентов, но только первый клиент, если продукт продается более чем одному клиенту. Для того чтобы слова выглядели так:
prod | cust
p1 | c1
p2 | c1
p3 | c2
Я пробовал это каждый, о чем я могу думать, но я не могу получить правильный результат. Очевидно, что ни одна отдельная группа, ни группа не будут работать (сами по себе), так как они возвратят строку p1, c2.
Я нашел этот question, который является очень близким, но я не могу понять, как его переписать, чтобы заставить его делать то, что мне нужно.
В довершение всего, все это в настоящее время должно работать в Access 2007 или более поздней версии, но в какой-то момент времени оно также должно работать и в MySQL.
Дополнительный кредит для всех, кто также присоединяется к результатам в таблице клиентов, чтобы я мог искать человекочитаемое имя из кода клиента, например. c1 = > Ключи Фред Бэггс
Ответы
Ответ 1
Основной вопрос:
SELECT prod, MIN(cust)
FROM yourTable
GROUP BY prod
Для "Бонуса":
SELECT T.prod,
T.cust,
YC.SomeCustomerAttribute1,
YC.SomeCustomerAttribute2
FROM (
SELECT prod, MIN(cust) AS first_cust
FROM yourProducts
GROUP BY prod
) AS T
JOIN yourCustomers AS YC ON YC.cust = T.first_cust
Ответ 2
Я собираюсь предположить, что у вас есть какой-то идентификатор, который указывает, кто является "первым". Столбец даты или столбец идентификации или что-то еще.
В моем примере я сделал это с идентификатором столбца order_id.
CREATE TABLE products (
order_id MEDIUMINT NOT NULL AUTO_INCREMENT,
prod char(2),
cust char(2),
qty int,
PRIMARY KEY (order_id)
);
INSERT INTO products (prod, cust, qty) VALUES
('p1', 'c1', 5),
('p1', 'c2', 10),
('p2', 'c1', 2),
('p3', 'c2', 8);
И затем, чтобы запустить ваши значения:
select p1.prod, p1.cust, p1.qty
from products p1
where not exists (select * from products p2
where p1.prod = p2.prod
and p2.order_id < p1.order_id)
где на каждой строке вы проверяете, есть ли другие клиенты, заказавшие ее раньше, чем вы. Если есть более ранний порядок, не перечислите эту строку. (Таким образом, not exists
)
Это синтаксис mysql, кстати, о котором вы говорите, мигрируете. (Эксперты по доступу должны отредактировать это соответствующим образом.)
Теперь, если у вас нет столбца, определяющего, что обозначает последовательность ввода заказов, вам нужен он. Любые схемы, которые полагаются на неявное row_numbering, основанное на порядке вставки, будут разваливаться в конце концов, так как "первая строка" не будет оставаться неизменной.
Ответ 3
если вы хотите, чтобы первый результат добавлял LIMIT 1
к вашему запросу, или используйте SELECT DISTINCT
для получения уникальных результатов.
как для вашего соединения, проверьте это:
SELECT * FROM TableA
INNER JOIN TableB
ON TableA.name = TableB.name
это приведет к тому, что все строки будут сопоставлять name
с таблицей A и таблицей B.
ИЗМЕНИТЬ
J Cooper прав, ms-access не имеет эквивалента LIMIT
. самый близкий TOP
, но я не думаю, что это поможет. извините, не использовали доступ с колледжа.
Ответ 4
"Первый" и min() не совпадают. Если вы действительно хотите сначала, попробуйте следующее:
declare @source table
(
prod varchar(10),
cust varchar(10),
qty int
)
insert into @source (prod, cust, qty) values ('p1', 'c1', 5)
insert into @source (prod, cust, qty) values ('p1', 'c2', 10)
insert into @source (prod, cust, qty) values ('p2', 'c1', 2)
insert into @source (prod, cust, qty) values ('p3', 'c2', 8)
select * from @source
declare @target table
(
prod varchar(10),
cust varchar(10),
qty int
)
insert into @target (prod)
select distinct prod from @source
update @target
set
cust = s.cust,
qty = s.qty
from @source s
join @target t on t.prod = s.prod
select * from @target