我需要计算product_rec_id匹配,分配,两个或多个供应商名称的次数。
例如,当用户输入 sarsa 和 bobbie25 时,我应该从下面的示例供应商表中获得值1。
这就是我所拥有的,而对我来说奇怪的是,这两个方法对关键字的表有效,但对供应商的表无效,Count总是返回值0.表几乎相似,可能是什么问题?
SELECT
Count(distinct product_rec_id)
FROM
vendors
INNER JOIN vendors_products ON vendors_products.vendor_rec_id = vendors.vendor_rec_id
WHERE
(vendors.name LIKE '%sarsa%') AND
(vendors.name LIKE '%bobbie25%')
对于Firebird 3,我将Then 1
更改为Then True
。
SELECT
Count((CASE
WHEN vendors.name LIKE '%sarsa%'
THEN 1
END) AND (CASE
WHEN vendors.name LIKE '%bobbie25%'
THEN 1
END)) AS TRows
FROM
vendors
INNER JOIN vendors_products ON vendors_products.vendor_rec_id = vendors.vendor_rec_id
WHERE
(vendors.name LIKE '%sarsa%' OR
vendors.name LIKE '%bobbie25%')
-
CREATE TABLE vendors (
vendor_rec_id INTEGER PRIMARY KEY NOT NULL,
company_broker_id INTEGER NOT NULL,
name VARCHAR (50) NOT NULL,
vendor_id VARCHAR (50),
store_url VARCHAR (255),
website_url VARCHAR (255)
);
CREATE TABLE vendors_products (
product_rec_id INTEGER NOT NULL,
vendor_rec_id INTEGER
);
-
vendors' table data:
60 2 bobbie25 73658 http://www.somewebsite.com/ http://www.somewebsite.com/
43 2 sarsa 61688 http://www.somewebsite.com/ http://www.somewebsite.com/
-
CREATE TABLE keywords (
keyword_rec_id INTEGER PRIMARY KEYNOT NULL,
keyword VARCHAR (50) NOT NULL UNIQUE,
chart INTEGER NOT NULL
DEFAULT 0
);
CREATE TABLE keywords_products (
keyword_rec_id INTEGER NOT NULL,
product_rec_id INTEGER
);
供应商表中的vendor_rec_id和名称字段如下所示,这是供应商表的示例(从不存在任何空值):
vendor_rec_id name
-------------- -----------
60 bobbie25
43 sarsa
87 johnf
vendors_products 表中的vendor_rec_id和product_rec_id看起来像这样(一个供应商名称可以分配给许多产品)(从来没有任何空值):
vendor_rec_id product_rec_id
-------------- --------------
43 1
60 1
43 2
87 3
答案 0 :(得分:1)
这是我最终设法组合起来的。这没有问题。
现在,当用户输入多个关键字并想要提取与输入的所有关键字匹配的记录时,我可以使用此记录来获取记录计数和记录本身(不包括计数(*)选择)。
我确信有更好的方法可以完成这项工作,但这是我对SQL的有限经验所带来的。
Select Count(*) As TRows From
(Select
vendors_products.product_rec_id
From
vendors_products
Inner Join vendors On vendors_products.vendor_rec_id = vendors.vendor_rec_id
Where
(Lower(vendors.name) Like '%sarsa%' OR
Lower(vendors.name) Like '%bobbie25%')
Group By
vendors_products.product_rec_id
Having
Sum(Case
When lower(vendors.name) Like '%sarsa%'
Then 1
Else 0
End) > 0 And
Sum(Case
When lower(vendors.name) Like '%bobbie25%'
Then 1
Else 0
End) > 0
) MyCountResults
答案 1 :(得分:0)
最简单的解决方案是选择vendors_products
中具有给定供应商名称的条目的所有产品。
假设某个表products
的列product_id
,您可以使用
对要检查的每个供应商使用exists
:
with product_by_vendor as (
select vp.product_rec_id, v.name
from vendors v
inner join vendors_products vp on v.vendor_rec_id = vp.vendor_rec_id
)
select count(*)
from products p
where exists (
select *
from product_by_vendor
where product_rec_id = p.product_id
and name like '%sarsa%')
and exists (
select *
from product_by_vendor
where product_rec_id = p.product_id
and name like '%bobbie25%')
您要检查的每个供应商的inner join
:
with product_by_vendor as (
select vp.product_rec_id, v.name
from vendors v
inner join vendors_products vp on v.vendor_rec_id = vp.vendor_rec_id
)
select count(*)
from products p
inner join product_by_vendor pv1
on pv1.product_rec_id = p.product_id and pv1.name like '%sarsa%'
inner join product_by_vendor pv2
on pv2.product_rec_id = p.product_id and pv2.name like '%bobbie25%'
使用cross join
和ALL
谓词稍微模糊一点(以及特定于Firebird):
with product_by_vendor as (
select vp.product_rec_id, v.name, v.vendor_rec_id
from vendors v
inner join vendors_products vp on v.vendor_rec_id = vp.vendor_rec_id
),
vendors_x_products as (
select p.product_id, v.name, v.vendor_rec_id
from products p
cross join vendors v
)
select count(*)
from products p
where p.product_id = all (
select pv.product_rec_id
from vendors_x_products vp
left join product_by_vendor pv
on vp.product_id = pv.product_rec_id and vp.vendor_rec_id = pv.vendor_rec_id
where vp.product_id = p.product_id
and (vp.name like '%sarsa%' or vp.name like '%bobbie25%')
)
我确信可能有一种更简单的方法,但我现在无法想到它。