ahmed_sa Ответов: 1

Как написать запрос get counts of part by two fields onlinedata and offlinedata from general table ?


проблема

Как написать запрос получить количество деталей по двум полям OnlineData и OfflineData из общей таблицы ?

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

OnlineData      OfflineData          CountParts
www.spare.com    www.sic.vom             3
www.while.com    www.datacomer.com       0


Мне нужно написать запрос get count количество частей на каждый OnlineData и OfflineData, на которых есть текст 'Coca'

Принимается таблица значений из таблицы с общими и не имеют 'Кока' текста по принятым таблицы значений из таблицы достичь

на основе PartId и SourceType

это означает, что мне нужно подсчитать части, имеющие текст Coca из общей таблицы, и те же части, которые не имеют текста Coca из таблицы reach .

В качестве примера PartId : 200 имеют текст "Coca" на принятом значении из общей таблицы и не имеют текста "Coca" из таблицы Reach, что на самом деле мне нужно его подсчитать

если ничего то количество деталей будет равно 0

в месте соединения (табл достичь и общая таблица) и приняла значение тип источника=Accptedvlueid

соединение между таблицей reach и общей таблицей PartId .

Что я уже пробовал:

USE [Store]

CREATE TABLE [dbo].[AcceptedValue](
	[AcceptedId] [int] NOT NULL,
	[AcceptedName] [nvarchar](50) NULL,
 CONSTRAINT [PK_AcceptedValue] PRIMARY KEY CLUSTERED 
(
	[AcceptedId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]


CREATE TABLE [dbo].[General](
	[GeneralId] [int] NOT NULL,
	[PartId] [int] NULL,
	[SourceType] [nvarchar](50) NULL,
	[OnlineData] [nvarchar](200) NULL,
	[OfflineData] [nvarchar](200) NULL,
 CONSTRAINT [PK_General] PRIMARY KEY CLUSTERED 
(
	[GeneralId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]


CREATE TABLE [dbo].[Reach](
	[ReachId] [int] NULL,
	[PartId] [int] NULL,
	[SourceType] [nvarchar](50) NULL
) ON [PRIMARY]

GO
INSERT [dbo].[AcceptedValue] ([AcceptedId], [AcceptedName]) VALUES (500, N'CocaDone')
INSERT [dbo].[AcceptedValue] ([AcceptedId], [AcceptedName]) VALUES (502, N'CocaJes')
INSERT [dbo].[AcceptedValue] ([AcceptedId], [AcceptedName]) VALUES (510, N'ComSpare')
INSERT [dbo].[AcceptedValue] ([AcceptedId], [AcceptedName]) VALUES (512, N'ColNumber')
INSERT [dbo].[AcceptedValue] ([AcceptedId], [AcceptedName]) VALUES (550, N'KidleAtlanta')
INSERT [dbo].[AcceptedValue] ([AcceptedId], [AcceptedName]) VALUES (560, N'Helogin')
INSERT [dbo].[AcceptedValue] ([AcceptedId], [AcceptedName]) VALUES (900, N'CocaHard')
INSERT [dbo].[AcceptedValue] ([AcceptedId], [AcceptedName]) VALUES (905, N'CodSeries')
INSERT [dbo].[General] ([GeneralId], [PartId], [SourceType], [OnlineData], [OfflineData]) VALUES (120, 200, N'900', N'www.spare.com', N'www.sic.vom')
INSERT [dbo].[General] ([GeneralId], [PartId], [SourceType], [OnlineData], [OfflineData]) VALUES (125, 277, N'500', N'www.spare.com', N'www.sic.vom')
INSERT [dbo].[General] ([GeneralId], [PartId], [SourceType], [OnlineData], [OfflineData]) VALUES (129, 299, N'502', N'www.spare.com', N'www.sic.vom')
INSERT [dbo].[General] ([GeneralId], [PartId], [SourceType], [OnlineData], [OfflineData]) VALUES (130, 250, N'550', N'www.while.com', N'www.datacomer.com')
INSERT [dbo].[Reach] ([ReachId], [PartId], [SourceType]) VALUES (120, 200, N'905')
INSERT [dbo].[Reach] ([ReachId], [PartId], [SourceType]) VALUES (125, 277, N'510')
INSERT [dbo].[Reach] ([ReachId], [PartId], [SourceType]) VALUES (129, 299, N'512')
INSERT [dbo].[Reach] ([ReachId], [PartId], [SourceType]) VALUES (130, 250, N'560')

1 Ответов

Рейтинг:
2

CHill60

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

содержит ли принятое название "Кока" или нет?
Тогда я пытаюсь найти способ вырваться просто это ключевые данные - не беспокоясь ни о чем другом. В этом случае я мог бы сделать
select G.OnlineData, G.OfflineData,  
          CASE WHEN AcceptedName LIKE '%Coca%' THEN 1 else 0 END as includepart
from General G
left outer join AcceptedValue AV on AV.AcceptedId=G.SourceType
Обратите внимание, что таблица Reach не имеет к этому отношения, поэтому я ее проигнорировал. Этот код даст мне результаты
OnlineData	OfflineData	includepart
www.spare.com	www.sic.vom		1
www.spare.com	www.sic.vom		1
www.spare.com	www.sic.vom		1
www.while.com	www.datacomer.com	0
Вместо 1 и 0 я мог бы так же легко использовать " да " и "нет", но 1 и 0 делают следующий шаг действительно легким.

Мне нужно иметь эти результаты где-то, чтобы использовать их на следующем шаге, который будет использовать GROUP BY [OnlineData], [OfflineData] и SUM эта промежуточная колонка [includepart]

Мне бы не помешал временный столик ...
if OBJECT_ID('tempdb..#interim_step', 'U') is not null drop table #interim_step
select G.OnlineData, G.OfflineData,  CASE WHEN AcceptedName LIKE '%Coca%' THEN 1 else 0 END as includepart
into #interim_step
from General G
left outer join AcceptedValue AV on AV.AcceptedId=G.SourceType
Или я мог бы использовать табличную переменную
declare @interim_step table ([OnlineData] [nvarchar](200) NULL,	[OfflineData] [nvarchar](200) NULL, includepart int NOT NULL)
insert into @interim_step
select G.OnlineData, G.OfflineData,  CASE WHEN AcceptedName LIKE '%Coca%' THEN 1 else 0 END as includepart
from General G
left outer join AcceptedValue AV on AV.AcceptedId=G.SourceType


Или я мог бы использовать свои личные предпочтения, общее табличное выражение (см. Обобщенные табличные выражения (введение в КТР-х) - необходимые для SQL[^])
;with CTE AS
(
	select G.OnlineData, G.OfflineData,  CASE WHEN AcceptedName LIKE '%Coca%' THEN 1 else 0 END as includepart
	from General G
	left outer join AcceptedValue AV on AV.AcceptedId=G.SourceType
)
SELECT OnlineData, OfflineData, sum(includepart) as [count]
FROM CTE
GROUP BY OnlineData, OfflineData
ORDER BY OnlineData, OfflineData
Обратите внимание: определите точку с запятой перед объявлением CTE? Если вы опустите его и у вас будет другой код перед CTE вы получите ошибку
Ошибка:
Неверный синтаксис рядом с ключевым словом "with". Если этот оператор является общим табличным выражением, предложением xmlnamespaces или предложением контекста отслеживания изменений, то предыдущий оператор должен заканчиваться точкой с запятой.
Если вы сделаете это привычкой всегда использовать ;WITH вы сможете не только избежать ошибки, когда вы сначала пишете код, вы также сможете сделать это легко, чтобы вставить новый код в течение последующего обслуживания