简体   繁体   English

SQL 计数关系数据

[英]SQL count relationship data

I wonder how to add extra data into dataGridView with help of Stored Procedure我想知道如何在存储过程的帮助下向dataGridView添加额外数据

Note: This is must probably issue with my SQL query (not sure).注意:这可能是我的 SQL 查询的问题(不确定)。

I have following code which return my products data into dataGridView我有以下代码将我的产品数据返回到dataGridView

using (SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["SampleDatabaseWalkthrough.Properties.Settings.SampleDatabaseConnectionString"].ConnectionString))
{
  if (cn.State == ConnectionState.Closed)
    cn.Open();
  using (DataTable dt = new DataTable())
  {
    using (SqlCommand cmd = new SqlCommand("exec dbo.GetProducts", cn))
    {
      SqlDataAdapter adapter = new SqlDataAdapter(cmd);
      adapter.Fill(dt);
      dataGridViewProducts.DataSource = dt;
      dataGridViewProducts.AutoGenerateColumns = false;
    }
  }
}

And here is my default stored procedure associated to code above:这是与上述代码关联的默认存储过程:

CREATE PROCEDURE [dbo].[GetProducts]
AS
    begin
    SELECT * from Products
    end

Combined of codes above works 100% .以上代码的组合工作 100% Now I want to add relationship table data into my products query as following:现在我想将关系表数据添加到我的产品查询中,如下所示:

CREATE PROCEDURE [dbo].[GetProducts]
AS
    begin
    SELECT * from Products p
    Join Serials s ON s.Id = p.Id
    end

This stored procedure above supposed to return data of my products + count of each product serials.上面的这个存储过程应该返回我的产品数据+每个产品序列的计数。 (ie): (IE):

Name: Product 1
Origin: Local
Serials: 15 <-- this is count of relationship table

Screenshot:截屏:

一

Issue问题

As you see in my screenshot both my products are receiving serial numbers in column serials BUT only my product Table has serial number, Therefore in serials column of product table it should say 2 and for product Lamp it should say 0正如你在我的截图中看到我的两个产品被列接收序列号serials ,但只有我的产品Table有序列号,因此在serials的产品表列,应该说2和产品的Lamp应该说0

Update更新

I just noticed that in my query I should get serials like Join Serials s ON s.ProductId = p.Id instead I am getting them like this Join Serials s ON s.Id= p.Id .我只是注意到,在我的查询中,我应该得到像Join Serials s ON s.ProductId = p.Id而不是像这样Join Serials s ON s.Id= p.Id

BUT the problem with that is this time I'm getting 2 Table and no Lamp product in my dataGridView (as lamp does not have any serial associated with it).但问题是这次我在我的dataGridView得到 2 个表并且没有 Lamp 产品(因为灯没有任何与之相关的序列)。

Any suggestion?有什么建议吗?

Update 2更新 2

Serials table schema序列表模式

CREATE TABLE [dbo].[Serials] (
    [Id]        INT           NOT NULL,
    [ProductId] INT           NOT NULL,
    [Serial]    NVARCHAR (50) NOT NULL,
    [Sold] bit NOT NULL DEFAULT 0,
    PRIMARY KEY CLUSTERED ([Id] ASC),
    CONSTRAINT [FK_Serials_Products] FOREIGN KEY ([ProductId]) REFERENCES [dbo].[Products] ([Id])
);

Try this:试试这个:

SELECT p.*
  ,(SELECT Count(*) FROM Serials s WHERE s.ProductId = p.Id) AS Serials
FROM Products p

When you join onto Serials you end up with one row in the response for each row in the Serials table.当您加入Serials您最终在Serials表中每一行的响应中都有一行。 There are other ways to achieve the same resultset, but this should be the simplest to understand.还有其他方法可以实现相同的结果集,但这应该是最容易理解的。


UPDATE:更新:

what I'm trying to do is to count product serials if they are not sold yet (Sold = 0)我想要做的是计算尚未出售的产品序列号(已售出 = 0)

To demonstrate different ways to express this, you may be able to extend this concept to your needs:为了演示不同的表达方式,您可以将这个概念扩展到您的需要:

SELECT p.*
  ,(SELECT Count(*) 
    FROM Serials s 
    WHERE s.ProductId = p.Id
      AND s.Sold = 0) AS SerialsRemaining
FROM Products p

You could add any number of additional columns like this, but the execution time is very inefficient.您可以像这样添加任意数量的附加列,但执行时间非常低效。

We can use a join instead to acheive the same reocrd set, however we must include all the fields in the Products table in the GROUP BY clause for this to work:我们可以使用连接来实现相同的记录集,但是我们必须在GROUP BY子句中包含Products表中的所有字段才能使其工作:

In this query SUM is used with a CASE expression, where CASE determines which column to include in the aggregate:在此查询中, SUMCASE表达式一起使用,其中CASE确定要包含在聚合中的列:

SELECT p.*
   , COUNT(s.Id) AS Total
   , SUM(CASE s.Sold WHEN 1 THEN 1 ELSE 0 END) AS Sold
   , SUM(CASE s.Sold WHEN 0 THEN 1 ELSE 0 END) AS Remaining
FROM Products p
LEFT OUTER JOIN Serials s ON (s.ProductId = p.Id)
GROUP BY p.Id,p.Photo,p.Name,p.Qty,p.Origin,p.[Buy Price],p.[Sell Price],p.SN 

For a final closure, have a look at this fiddle if you want to experiment: http://sqlfiddle.com/#!18/64f32/2对于最终关闭,如果您想进行实验,请查看此小提琴: http : //sqlfiddle.com/#!18/64f32/2

try this.试试这个。 Performance of join is always better as compared to subquery.与子查询相比,join 的性能总是更好。

SELECT P.*, COUNT(s.serail)serialCount
FROM product P
LEFT OUTER JOIN serail S ON (p.id = s.PID)
GROUP BY P.id, P.Name, P.Quantity -- _and all other columns of product table_

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM