【问题标题】:Left join showing 2 results when there should be 0当应该有 0 时,左连接显示 2 个结果
【发布时间】:2015-03-23 14:36:20
【问题描述】:

这是我的 sql:

SELECT * 
FROM   products 
       LEFT JOIN bids 
              ON bids.bids_item = products.id 
       LEFT JOIN orders 
              ON orders.orders_product = products.id 
WHERE  products.username = ? 
       AND Now() > products.enddate 
       AND enabled = 1
       OR bids > 0
GROUP  BY products.id 
ORDER  BY bids.bids_amount DESC 

我正在尝试从产品表、订单表和出价表中选择产品,假设您是使用我的网站的用户,您想购买 2 种产品,第 1 项和第 2 项。您从第 1 项开始,即拍卖,您对该项目出价,以下信息进入出价表:

bids_amount, 
bids_id, 
bids_item, 
bids_timestamp

在产品表中,当您出价时,我有一个 id、一个 enddate 和一个 bids 行,它将 +1 添加到 bids 行并将产品 id 插入到 bids_item。为了衡量一个项目何时结束,我将数据与结束日期进行比较。然后我使用上面的 sql 来检查具有这些细节的已售商品。无论如何,现在您知道出价是如何运作的,现在让我们假设您正在购买“立即购买”商品。您看到您喜欢的产品 2 并决定将其添加到您的购物车,然后决定结帐(这会将以下信息添加到订单中减去一些)

orders_id, 
orders_item, 
orders_username, 
orders_status

所以从技术上讲,我需要一个 sql 查询来检查bids > 0 或者orders and bids 表中是否有一行。我的表结构:

出价

CREATE TABLE `bids` (
 `bids_id` int(11) NOT NULL AUTO_INCREMENT,
 `bids_item` int(11) NOT NULL,
 `bids_username` varchar(100) NOT NULL,
 `bids_amount` decimal(11,8) NOT NULL,
 `bids_date` datetime NOT NULL,
 `bids_timestamp` int(25) NOT NULL,
 PRIMARY KEY (`bids_id`),
 UNIQUE KEY `bids_id` (`bids_id`)
) ENGINE=InnoDB AUTO_INCREMENT=139 DEFAULT CHARSET=latin1

订单

CREATE TABLE `orders` (
 `orders_id` int(11) NOT NULL AUTO_INCREMENT,
 `orders_product` int(11) NOT NULL,
 `orders_username` varchar(100) NOT NULL,
 `orders_status` int(11) NOT NULL,
 `orders_firstname` varchar(100) NOT NULL,
 `orders_lastname` varchar(100) NOT NULL,
 `orders_address1` varchar(100) NOT NULL,
 `orders_address2` varchar(100) NOT NULL,
 `orders_zipcode` varchar(100) NOT NULL,
 `orders_city` varchar(100) NOT NULL,
 `orders_country` varchar(100) NOT NULL,
 `orders_shipped` int(11) NOT NULL,
 `orders_btcaddress` varchar(100) NOT NULL,
 PRIMARY KEY (`orders_id`)
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=latin1

产品

CREATE TABLE `products` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `title` varchar(100) NOT NULL,
 `description` text NOT NULL,
 `shortdescription` varchar(100) NOT NULL,
 `price` decimal(11,6) NOT NULL,
 `username` varchar(50) NOT NULL,
 `buyitnow` int(11) NOT NULL,
 `enddate` datetime NOT NULL,
 `purchases` int(11) NOT NULL,
 `bids` int(11) NOT NULL,
 `startingprice` decimal(11,6) NOT NULL,
 `date` datetime NOT NULL,
 `itemcondition` varchar(100) NOT NULL,
 `international` int(11) NOT NULL,
 `shipsto` varchar(100) NOT NULL,
 `shipping` varchar(100) NOT NULL,
 `shippingcost` decimal(11,6) NOT NULL,
 `shippingtime` int(11) NOT NULL,
 `location` varchar(100) NOT NULL,
 `enabled` int(11) NOT NULL DEFAULT '1',
 `category` varchar(50) NOT NULL,
 `quantity` int(11) NOT NULL,
 `offers` int(11) NOT NULL,
 `returns` int(11) NOT NULL,
 `images` text NOT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=93 DEFAULT CHARSET=latin1

我的 sql 显示的内容:

(84, 'balance', '', 'dfghgfds', '0.000000', 'admin', 0, '2015-03-19 17:40:24', 0, 0, '1.040000', '2015-03-18 13:21:40', 'new', 0, '', 'MyHermes', '1.000000', 0, 'United Kingdom', 1, '', 1, 0, 0, ''),
(85, 'dfghdsdgb\r\n', '', 'dfghgfds', '1.000000', 'admin', 1, '2015-03-19 17:41:06', 0, 0, '1.040000', '2015-03-18 13:21:40', 'new', 0, '', 'MyHermes', '1.000000', 0, 'United Kingdom', 1, '', 1, 0, 0, ''),

我需要它显示的内容:

没有,因为出价行 = 0,并且出价或订单中没有与该 product.id 匹配的行

这是我的产品行等:

CREATE TABLE IF NOT EXISTS `products` (
`id` int(11) NOT NULL,
  `title` varchar(100) NOT NULL,
  `description` text NOT NULL,
  `shortdescription` varchar(100) NOT NULL,
  `price` decimal(11,6) NOT NULL,
  `username` varchar(50) NOT NULL,
  `buyitnow` int(11) NOT NULL,
  `enddate` datetime NOT NULL,
  `purchases` int(11) NOT NULL,
  `bids` int(11) NOT NULL,
  `startingprice` decimal(11,6) NOT NULL,
  `date` datetime NOT NULL,
  `itemcondition` varchar(100) NOT NULL,
  `international` int(11) NOT NULL,
  `shipsto` varchar(100) NOT NULL,
  `shipping` varchar(100) NOT NULL,
  `shippingcost` decimal(11,6) NOT NULL,
  `shippingtime` int(11) NOT NULL,
  `location` varchar(100) NOT NULL,
  `enabled` int(11) NOT NULL DEFAULT '1',
  `category` varchar(50) NOT NULL,
  `quantity` int(11) NOT NULL,
  `offers` int(11) NOT NULL,
  `returns` int(11) NOT NULL,
  `images` text NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=94 DEFAULT CHARSET=latin1;

--
-- Dumping data for table `products`
--

INSERT INTO `products` (`id`, `title`, `description`, `shortdescription`, `price`, `username`, `buyitnow`, `enddate`, `purchases`, `bids`, `startingprice`, `date`, `itemcondition`, `international`, `shipsto`, `shipping`, `shippingcost`, `shippingtime`, `location`, `enabled`, `category`, `quantity`, `offers`, `returns`, `images`) VALUES
(84, 'balance', '', 'dfghgfds', '0.000000', 'admin', 0, '2015-03-19 17:40:24', 0, 0, '1.040000', '2015-03-18 13:21:40', 'new', 0, '', 'MyHermes', '1.000000', 0, 'United Kingdom', 1, '', 1, 0, 0, ''),
(85, 'dfghdsdgb\r\n', '', 'dfghgfds', '1.000000', 'admin', 1, '2015-03-19 17:41:06', 0, 0, '1.040000', '2015-03-18 13:21:40', 'new', 0, '', 'MyHermes', '1.000000', 0, 'United Kingdom', 1, '', 1, 0, 0, ''),
(86, 'desk table\r\n', '', 'dfghgfds', '1.000000', 'admin', 1, '2015-03-25 13:21:40', 0, 0, '1.040000', '2015-03-18 13:21:40', 'new', 0, '', 'MyHermes', '1.000000', 0, 'United Kingdom', 1, '', 0, 0, 0, ''),
(87, 'ps3\r\n', '', 'dfghgfds', '1.000000', 'admin', 1, '2015-03-25 13:21:40', 0, 0, '1.040000', '2015-03-18 13:21:40', 'new', 0, '', 'MyHermes', '1.000000', 0, 'United Kingdom', 1, '', 0, 0, 0, ''),
(88, 'xbox one', '<div class="fullDetails">     <p>Xbox One brings together the best exclusive games like Titanfall and Halo, the most advanced multi-player and entertainment experiences you won''t find anywhere else.</p><ul><li>Parental controls allow you to set-up profiles for children to prevent unauthorised purchases and ensure they only access age appropriate content.</li><li>Game DVR keeps a rolling video record of gameplay and with Upload Studio you can edit clips, add voiceover and share them with your friends.</li><li>500GB hard drive give you plenty of memory for your games, demos, movies, apps, music and more.</li><li>Snap a game, live TV and apps like Netflix or YouTube side-by-side and switch quickly between them.</li><li>Experience the action like never before with the Xbox One Wireless Controller. New Impulse Triggers, redesigned thumbsticks and D-pad provide greater intensity, precision and comfort.</li><li>Keep your in-game communications crisp with the comfortable new Xbox One Chat Headset. Hear friends and foes in crystal-clear digital audio.</li><li>Includes Xbox One console, wireless controller, chat headset, HDMI cable, power supply, 14-Day Xbox Live Gold membership.</li><li>Built in blu-ray disc drive allows playback of blu-ray discs and 3D blu-ray discs.</li><li>500GB hard drive capacity.</li><li>Size H8, W27.4, D33.2cm.</li><li>EAN: 885370808315.</li></ul> </div>  <!--                : 15113product.longdescription                    <tr><td>Name:</td> <td> product.longdescription </td></tr>                      <tr><td>DataType:</td> <td> MarketingContent </td></tr>                     <tr><td>ActivityIdentifier UniqueID:</td> <td> 11503 </td></tr>                     <tr><td>ActivityIdentifier Name:</td> <td> pdp_proddesc2colleft </td></tr>                      <tr><td>CampaignName:</td> <td>  </td></tr>                     <tr><td>ActivityFormat:</td> <td> web </td></tr>                    <tr><td>ActivityPriority:</td> <td> 0 </td></tr>              <tr><td>Url Link:</td> <td>  </td></tr>                                                 <tr><td>Marketing Text:</td> <td> prod.long.description.content </td></tr>                  <tr><td>Location:</td> <td>  </td></tr>                                 <tr><td>Format UniqueID:</td> <td> 10009 </td></tr>                 <tr><td>Format Name:</td> <td> Widget </td></tr>                        <tr><td>Content Mime Type:</td> <td>  </td></tr>                    <tr><td>Name:</td> <td>  </td></tr>                                         <tr><td>Short Description:</td> <td>  </td></tr>                                                <tr><td>Image:</td> <td>  </td></tr>                                                                                            -->  <div class="additionalinfo" id="additionalinfo">       <h4>Additional Information</h4>             <p><img src="/wcsstore/argos/en_GB/images/p8/icon_dagger.gif" alt="This item is excluded from the 30 day money back guarantee. See the Additional Information panel for full details." nmcxl33="1">         Please note that this product is excluded from our 30 Day Money Back Guarantee. This does not affect your statutory rights.</p>         <p>Prices correct as displayed but are subject to change</p>                         </div>', 'dfghgfds', '1.000000', 'admin', 1, '2015-03-25 13:21:40', 0, 0, '1.040000', '2015-03-18 13:21:40', 'new', 0, '', 'MyHermes', '1.000000', 0, 'United Kingdom', 1, '', 0, 0, 0, ''),
(89, 'xbox 360', '', 'dfghgfds', '1.000000', 'admin', 1, '2015-03-25 13:21:40', 0, 0, '1.040000', '2015-03-18 13:21:40', 'new', 0, '', 'MyHermes', '1.000000', 0, 'United Kingdom', 1, '', 0, 0, 0, ''),
(90, 'camera', '', 'dfghgfds', '1.000000', 'admin', 1, '2015-03-25 13:21:40', 0, 0, '1.040000', '2015-03-18 13:21:40', 'new', 0, '', 'MyHermes', '1.000000', 0, 'United Kingdom', 1, '', 0, 0, 0, ''),
(91, 'sd card', 'main descript blah blah blah blah blah blahblah blah blahblah blah blahblah blah blahblah blah blahblah blah blahblah blah blahblah blah blahblah blah blah', 'blah blah blah', '1.000000', 'demo', 0, '2015-03-26 17:21:00', 0, 0, '1.040000', '2015-03-18 13:21:40', 'new', 0, '', 'MyHermes', '1.000000', 0, 'United Kingdom', 1, '', 1, 0, 0, ''),
(92, '22 Inch lg Tv lg22ma33d-pz', '<p>dfd</p>', 'dfghgfds', '0.000000', 'admin', 0, '2015-03-26 23:53:02', 0, 0, '99999.999999', '2015-03-19 23:53:02', 'new', 0, '', 'MyHermes', '1.000000', 0, 'United Kingdom', 1, '', 1, 0, 0, ''),
(93, '22 Inch lg Tv lg22ma33d-pz', '', 'dfghgfds', '0.000000', 'admin', 0, '2015-03-27 14:42:47', 0, 0, '1.000000', '2015-03-20 14:42:47', 'new', 0, '', 'MyHermes', '1.000000', 0, 'United Kingdom', 1, '', 1, 0, 0, '');

【问题讨论】:

  • 您可以使用sqlfiddle.com 为您的架构制作一个沙箱,可能会让别人更容易理解您的问题
  • @randommman:你已经弄清楚了吗?如果是,是否有任何有用的答案足以被标记为已接受?如果没有,您能否提供更多详细信息,以便我们尝试为您提供帮助? :-)

标签: php mysql sql


【解决方案1】:

大概,您希望where 子句是:

WHERE (products.username = ? AND Now() > products.enddate) AND
      (enabled = 1 OR bids > 0)

而不是它被解释的方式:

WHERE (products.username = ? AND
       Now() > products.enddate AND
       enabled = 1
      ) OR bids > 0

【讨论】:

  • 仍然显示 2 个产品,即使订单表或投标表中没有任何行
【解决方案2】:

我相信这是您需要的查询:

SELECT * 
FROM products 
LEFT JOIN bids ON bids.bids_item = products.id
LEFT JOIN orders ON orders.orders_product = products.id
WHERE ( 
           products.username = ? 
           AND Now() > products.enddate 
           AND enabled = 1 
      ) 
      AND 
      ( 
           bids > 0 
           OR orders.orders_product IS NOT NULL 
           OR bids.bids_item IS NOT NULL 
      )      
GROUP BY products.id 
ORDER BY bids.bids_amount DESC;

因为您需要已启用的产品,这些产品已经结束并且(我猜这里)被具有特定@的用户赢得 987654322@。 此外,您想对该产品OR 有一些出价,您希望在orders OR bids 表中记录。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    相关资源
    最近更新 更多