【问题标题】:Nested SQL queries in asp.netasp.net 中的嵌套 SQL 查询
【发布时间】:2012-01-02 16:14:04
【问题描述】:

我必须运行 1 个查询,然后再运行第一个查询的结果。我意识到我可以将第一个结果集放入数组中,然后遍历数组,但是有没有办法只嵌套查询,这样我就不必弄乱数组了?

这是我当前的代码:

    SqlConnection conn2 = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["wesdb1SQL"].ToString());
    SqlCommand strSQL2;
    SqlDataReader itemReader2;

    using (SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["wesdb1SQL"].ToString()))
    using (SqlCommand strSQL = conn.CreateCommand())
    {
        strSQL.CommandText = "SELECT item_id,item_lot,item_title,item_est_lo,item_est_hi,item_timed_start,item_reserve FROM tblItem WHERE (item_sale_id=@item_sale_id) ORDER BY item_lot";

        strSQL.Parameters.Add(new SqlParameter("@item_sale_id", SqlDbType.VarChar, 10, ParameterDirection.Input, true, 0, 0, "item_sale_id", DataRowVersion.Current, itemSaleId1_Var));

        try
        {
            conn.Open();
            using (SqlDataReader itemReader = strSQL.ExecuteReader())
            {
                if (itemReader.Read())
                {
                    using (conn2)
                    using (strSQL2 = conn2.CreateCommand())
                    {
                        strSQL2.CommandText = "SELECT TOP (1) MAX(tblBidHistory.bid_price) AS bid_price, tblMailList.mail_Email1, tblBidHistory.bid_bidder_id, tblMailList.mail_FirstName, tblMailList.mail_LastName, tblBidHistory.bid_item_id FROM tblBidHistory INNER JOIN tblBidder ON tblBidHistory.bid_bidder_id = tblBidder.bidder_number AND (tblBidder.bidder_sale_id=@item_sale_id) INNER JOIN tblMailList ON tblBidder.bidder_mail_id = tblMailList.mail_ID GROUP BY tblMailList.mail_Email1, tblBidHistory.bid_bidder_id, tblMailList.mail_FirstName, tblMailList.mail_LastName, tblBidHistory.bid_item_id,tblBidHistory.bid_type,tblBidHistory.bid_date HAVING (tblBidHistory.bid_item_id=@item_id) AND (tblBidHistory.bid_type = '2') ORDER BY bid_price DESC,bid_date DESC";

                        strSQL2.Parameters.Add(new SqlParameter("@item_sale_id", SqlDbType.VarChar, 10, ParameterDirection.Input, true, 0, 0, "item_sale_id", DataRowVersion.Current, itemSaleId1_Var));
                        strSQL2.Parameters.Add(new SqlParameter("@item_id", SqlDbType.VarChar, 10, ParameterDirection.Input, true, 0, 0, "item_id", DataRowVersion.Current, itemReader["item_id"].ToString()));

                        try
                        {
                            conn2.Open();
                            using (itemReader2 = strSQL2.ExecuteReader())
                            {
                                if (itemReader2.Read())
                                {
                                    if (count % 2 == 0)
                                    {
                                        results_Var += "<tr><td colspan=\"2\"><font size=\"2\">" + itemReader["item_lot"].ToString() + " - <u>" + itemReader["item_title"].ToString() + "</u></font></td><td><font size=\"2\">$" + itemReader["item_est_lo"].ToString() + " - $" + itemReader["item_est_hi"].ToString() + "</font></td><td>" + itemReader2["bid_price"].ToString() + " - " + itemReader2["bid_bidder_id"].ToString() + " (" + itemReader2["mail_FirstName"].ToString() + " " + itemReader2["mail_LastName"].ToString() + ")</td><td><font size=\"2\">$" + itemReader2["bid_price"].ToString() + "</font></td></tr>";
                                    }
                                    else
                                    {
                                        results_Var += "<tr><td colspan=\"2\" bgcolor=\"#b0e0e6\"><font size=\"2\">" + itemReader["item_lot"].ToString() + " - <u>" + itemReader["item_title"].ToString() + "</u></font></td><td><font size=\"2\">$" + itemReader["item_est_lo"].ToString() + " - $" + itemReader["item_est_hi"].ToString() + "</font></td><td>" + itemReader2["bid_price"].ToString() + " - " + itemReader2["bid_bidder_id"].ToString() + " (" + itemReader2["mail_FirstName"].ToString() + " " + itemReader2["mail_LastName"].ToString() + ")</td><td><font size=\"2\">$" + itemReader2["bid_price"].ToString() + "</font></td></tr>";
                                    }
                                }
                                itemReader2.Close();
                            }
                        }
                        catch (Exception e1)
                        {
                            throw new Exception(e1.Message);
                        }
                        finally
                        {
                            conn2.Close();
                        }
                    }
                }
                itemReader.Close();
            }
        }
        catch (Exception e2)
        {
            throw new Exception(e2.Message);
        }
        finally
        {
            conn.Close();
        }
    }

这两个查询的输出用于创建包含多行数据的表。每一行是数据库中的一个项目,其中包含最高出价者的信息,包括出价本身,以及一些类别信息。类别信息是第一个查询,唯一项目信息是第二个查询(在这里您可以看到使用两个结果集构建的表行)。

编辑

我稍微更改了 xQbert 查询并最终得到:

SELECT MAX(BH.bid_price) AS bid_price, ML.mail_Email1, BH.bid_bidder_id,  ML.mail_FirstName, ML.mail_LastName, BH.bid_item_id, I.item_lot, I.item_title,  I.item_est_lo, I.item_est_hi, I.item_timed_start, I.item_reserve  
FROM tblBidHistory BH 
INNER JOIN tblBidder B  ON BH.bid_bidder_id = B.bidder_number   AND (B.bidder_sale_id=@item_sale_id) 
INNER JOIN tblMailList ML   ON B.bidder_mail_id = ML.mail_ID 
INNER JOIN tblItem I   ON I.Item_ID = BH.Bid_item_id 
WHERE (I.item_sale_id=@item_sale_id) And (BH.bid_type = '2') 
GROUP BY ML.mail_Email1, BH.bid_bidder_id, ML.mail_FirstName, ML.mail_LastName, BH.bid_item_id, BH.bid_type, BH.bid_date, I.item_lot, I.item_title, I.item_est_lo, I.item_est_hi, I.item_timed_start, I.item_reserve
ORDER BY I.Item_Lot

这给了我数据,但它给了我每个项目的每个投标人,而不是每个项目的最高投标人。我不确定是否需要进行不同的分组,或者使用子查询。

另外,为此,我只进行了 1 次查询。但是,我仍然想知道如何在 SQL 中进行嵌套查询。

【问题讨论】:

  • 您使用的是什么数据库?
  • SQL。如果你要求除此之外的东西,我不知道。对不起。我怎么知道呢?
  • 查看一些示例预期输出真的很有用。 MS-SQL(2005/2008 等)、MySQL、Oracle、DB2、PostGres,
  • nikAdmin 想知道您是否使用 SQL Server、Oracle、mySQL 等。连接字符串会告诉您,但如果您想发布它以显示,请务必删除 PASSWORD 和 USERID从它。
  • NiKAdmin,基于他的查询代码中对 TOP(1) 的使用,我假设它是 Microsoft SQL Server

标签: asp.net sql sql-server nested-queries


【解决方案1】:

试试:

select * from
(SELECT i.item_id,
       i.item_lot,
       i.item_title,
       i.item_est_lo,
       i.item_est_hi,
       i.item_timed_start,
       i.item_reserve,
       h.bid_price,
       l.mail_Email1,
       h.bid_bidder_id,
       l.mail_FirstName,
       l.mail_LastName,
       h.bid_item_id,
       row_number() over (partition by i.item_id 
                          order by h.bid_price DESC, h.bid_date DESC) rn
 FROM tblItem i 
 INNER JOIN tblBidHistory h
         on i.item_id = h.bid_item_id=i.item_id AND h.bid_type = '2' 
 INNER JOIN tblBidder b
         ON h.bid_bidder_id = b.bidder_number AND b.bidder_sale_id=i.item_sale_id
 INNER JOIN tblMailList l
         ON b.bidder_mail_id = l.mail_ID 
 WHERE i.item_sale_id=@item_sale_id) v
where rn=1

【讨论】:

  • 我尝试将 row_number() 函数(直到并包括 rn 的整行)添加到我的 select 语句的末尾,然后将其全部包装在另一个 select 语句中,其中 rn=1 并收到错误 > ORDER BY 子句在视图、内联函数、派生表、子查询和公用表表达式中无效,除非还指定了 TOP 或 FOR XML。我将 order by 子句移到第一个 select 语句之外并按 v.column 排序,然后开始收到错误消息,指出 tblItem.item_id (和其他)不在 group by 或聚合函数中,无法选择。
  • 当我使用整个查询时,我收到错误Incorrect syntax near '('.
  • @James:抱歉,我刚刚注意到缺少, - 立即尝试。
  • 别担心,我也没有注意到。不得不在这里更改一件事并添加另一件事。在第一个inner join on 语句中,我取出了其中一个 i.item_id = 因为它在那里两次,并且我将 order by item_lot 添加到整个语句的末尾。这真的很接近。我现在每件商品只有一排,但这不是出价最高的排,而且有些排完全缺失。当然,我明白为什么......这些没有投标人数据,我们使用的是内连接而不是外连接。但仍然有一个问题,它没有拉出最高出价/出价者。
  • 这真的很奇怪。当我将此查询直接放在 SQL 界面中时,它确实提取了正确的数据。但是当我在我的页面上使用查询时,它没有。
【解决方案2】:

我非常怀疑以下内容是否正确:假设过多且对问题缺乏理解:但这是加入它们的一种方式 假设项目通过 Bid_Item_ID 加入 BH 为 I.Item_lot 添加了 order by 并添加了项目数据 添加了要选择和分组依据的项目数据。

SELECT TOP (1) MAX(BH.bid_price) AS bid_price, ML.mail_Email1, BH.bid_bidder_id,
  ML.mail_FirstName, ML.mail_LastName, BH.bid_item_id, I.item_lot, I.item_title,
  I.item_est_lo, I.item_est_hi, I.item_timed_start, I.item_reserve  
FROM tblBidHistory BH
INNER JOIN tblBidder B
  ON BH.bid_bidder_id = B.bidder_number 
  AND (B.bidder_sale_id=@item_sale_id) 
INNER JOIN tblMailList ML 
  ON B.bidder_mail_id = ML.mail_ID
INNER JOIN tblItem I 
  ON I.Item_ID = BH.Bid_item_id
WHERE (I.item_sale_id=@item_sale_id)
GROUP BY ML.mail_Email1, BH.bid_bidder_id, 
  ML.mail_FirstName, ML.mail_LastName, BH.bid_item_id, BH.bid_type, BH.bid_date,
  I.item_lot, I.item_title, I.item_est_lo, I.item_est_hi, I.item_timed_start, 
  I.item_reserve  
HAVING (BH.bid_item_id=@item_id) AND (BH.bid_type = '2') 
ORDER BY I.Item_Lot, BH.bid_price DESC, BH.bid_date DESC

【讨论】:

  • 我认为 OP 希望对销售中的每件商品获得最高、最新的出价,而不是对销售中的任何商品的最高、最新出价。
  • @MarkBannister 是的,没错。我正在尝试为同一销售中的每件商品获取它。
  • 经过小周后,我得到了所有数据,但在某些情况下,我得到了多行相同的数据。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多