SQL Query - one column must be distinct, restricted column must be most recent

技术标签: SQL.  清楚的  分类

I have a CATEGORIES table that links to an ITEMS table (one to many). Each item table could have multiple barcodes in the BARCODES table (one to many).

The idea is that a new barcode may be added against an item at some point, but the old data is stored in the BARCODES table so that if a search is done with an order with last year's data, the item and category of the old barcode can still be found quickly.

Hope that makes sense - it's a bit of an oversimplification.

Example of my tables:

CATEGORIES TABLE
ID   NAME        CODE    ACCOUNTING_REFERENCE
1    Beverages   BEV     Stock_Beverages
2    Pies        PIE     Stock_Pies
3    Chips       CHP     Stock_Chips

ITEMS TABLE
ID   CATEGORY_ID  DESCRIPTION                 BASE_COST
1    1            Red Bull (single)           $4.50
2    2            Ponsonby Pie - Mince Cheese $2.99
3    1            Coke Can (single)           $3.50
4    2            Big Ben - Steak Pepper      $1.99

BARCODES TABLE
ID  ITEM_ID  BARCODE   ACTIVE_FROM
1   1        XSD123    2009/10/11
2   2        AXF123    2009/10/12
3   3        XYZ234    2009/10/11
4   1        NEW001    2010/01/05
5   1        NEW002    2010/01/05*
  • I know it doesn't make sense in this scenario to have two barcodes entered on the same day. Ignore that this looks like bad data. This example is just an analogy for what I'm actually doing - in the real world application that mirrors this structure, it makes sense to have two 'BARCODES' entered on the same day. I'd like to discuss the real data openly, but I'm not free to do so - I'm sorry if it's confusing.

I am attempting to display item information to the user. I want to return from SQL record per item, for all items. The returned information should include category name, code, and accounting references for the lines - duplicates of these columns are fine. The query needs to return item description and base cost.

This much I can do.

I also want the query to return the 最近 barcode for the item. In the cases where there are two barcodes entered for an item on the same day, it isn't hugely important which one I display - although displaying the higher of the two (or more) BARCODE.ID fields would be a nice touch.

Also, it is possible that items may exist without any barcodes against them, in which case I want to return a null entry.

My desired result set would look something like this:

ITEM_ID   DESCRIPTION                  BASE_COST  CATEGORY_NAME CATEGORY_CODE  ACCOUNTING_REFERENCE  BARCODE
1         Red Bull (single)            $4.50      Beverages     BEV            Stock_Beverages       NEW002
2         Ponsonby Pie - Mince Cheese  $2.99      Pies          PIE            Stock_Pies            AXF123
3         Coke Can (single)            $3.50      Beverages     BEV            Stock_Beverages       XYZ234
4         Big Ben - Steak Pepper       $1.99      Pies          PIE            Stock_Pies            <null>

I can't work out how to add the BARCODE column to this result set, given the tables above.

In case I haven't been clear: I need to know how to structure a SQL query that will give me exactly the result above, given the data I've presented.

It's a requirement that the ITEM_ID column in my result set be distinct. I can't just restrict the stale entries in memory, and if I bubble up multiple ITEM_ID's it breaks a PK/FK relationship used elsewhere in the application I'm touching up.

For the record, I've had a look around the site on anything related to distinct sql columns to answer this question. I found a lot of entries, but couldn't seem to get any of the suggested solutions to work for me. Perhaps I'm just dense - it's getting late, and I may not be thinking straight. Apologies if I've missed something obvious.

编辑

Gabe gave a good answer below, and I realized I should have been clearer.

Gabe's answer doesn't work for me, because occasionally in my data I have two barcodes against the same item with the same timestamp. When I tried his code, I wound up with multiple items being returned whenever an item had two barcodes placed against it on the same day.

This is really counter-intuitive, so it's my fault for not communicating properly. Essentially, the scenario described above isn't actually the data I'm working from. I'm not at liberty to discuss the database I'm working on publicly, so I have to rename everything in the examples I use.

I've adjusted the problem above. I know it seems ridiculous to have two barcodes entered with the same timestamp - rest assured that it makes sense that this could happen in the actual database.

EDIT (again)

The answers of both Gabe and 西蒙 工作。 I chose Gabe's as the answer, simply because I found his statement the most legible.

That said, I also like 西蒙's because it shows a syntax for using SQL that I'm not familiar with - it's good to see an unfamiliar syntax in action.

At some point I need to benchmark the two methods to see which is faster. With my sample data, they're currently equal - although I expect I could change that with a bit of work populating my database with a few thousand more records and revising my indexes.

谢谢您的帮助。

看答案

It sounds like you want a correlated subquery. Roughly, this:

 select *
from ITEMS
join BARCODES as B on ITEMS.ID = B.ITEM_ID
join CATEGORIES on CATEGORIES.ID = ITEMS.CATEGORY_ID
where B.ACTIVE_FROM =
    (select max(ACTIVE_FROM)
     from BARCODES as B2
     where B2.ITEM_ID = B.ITEM_ID)

To handle the situation where there is no barcode for a given item you need an outer join and to give only one barcode when there are many you need an additional subquery. In ANSI SQL, it might look something like this:

 select *
from ITEMS
LEFT OUTER join BARCODES as B on ITEMS.ID = B.ITEM_ID
join CATEGORIES on CATEGORIES.ID = ITEMS.CATEGORY_ID
where B.ACTIVE_FROM =
    (select max(ACTIVE_FROM)
     from BARCODES as B2
     where B2.ITEM_ID = B.ITEM_ID)
    AND B.ID =
    (SELECT MAX(ID)
     FROM BARCODES AS B3
     WHERE B3.ITEM_ID = B.ITEM_ID)
    OR ACTIVE_FROM IS NULL

智能推荐

error : Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in

MySql 5.5和MySql 5.6的区别:5.5 只能有一个Timestamp,将其中一列类型改为datetime类型就可以解决 根据下面帖解决:http://www.jb51.net/article/50878.htm...

jpa使用 at least one user library must be selected问题

at least one user library must be selected实际就是建立一个目录,导入三个包即可 ①、 eclipselink.jar ②、javax.persistence.source_2.1.0.v201304241213.jar ③、javax.persistence_2.1.0.v201304241213.jar (注:本系列笔记是在学习尚硅谷JPA课程...

pyteeseract使用报错Error: one input ui-file must be specified解决

  Python在图像识别有天然的优势,今天使用pytesseract模块时遇到一个报错:“Error: one input ui-file must be specified”。   环境:windows + Python3   根据报错缺少:Tesseract-OCR ,看好多都是在github上找到windows版本的下载地址:https://github.com/t...

运行 webpack 出现One CLI for webpack must be installed. These are recommended choices......

最近在安装好webpack后,使用时,提示 解决方案依然是需要全局安装webpack-cli 如下: npm -i webpack-cli -g  或者 npm install webpack-cli  在项目里再做一个本地安装: npm -i webpack -D 或者 npm install webpack -D...

.ui调用pyuic出现 one input ui-file must be specified错误

依据网上的教程,整理了配置pyqt进入pycharm里部分可能存在问题的地方。 1. 部分cmd调用pip install 时会默认把.exe文件(designer、uic、rcc)安装到对应的scripts文件夹里,而不是大多数教程里提到的site- packages的pyqt5_tools里。 2.在pycharm里配置时,Arguments可以选填。 3.Working derec...

猜你喜欢

pycharm中Error: one input ui-file must be specified报错(Anaconda环境)

我的pycharm是配置了anaconda环境的。 在正确安装了qtdesigner后,.ui文件转.py文件总是报错。 踩了许多雷,弄了好大一会才弄好。特在此分享给有需要的人。 首先是为什么会报错。 参看了许多博文,确实如他们所说,是由于PYUIC文件的路径错误。 先说正确的配置 1 正确的Qtdesigner路径 program: 我是用的是第三个:D-anaconda-scripts-des...

TemplateSyntaxError - 'staticfiles' is not a registered tag library. Must be one of:

Pycharm中: {% load staticfiles %} and {% load adminstatic %} were deprecated in Django 2.1, and removed in Django 3.0. If you have any of the following in your html: {% load staticfiles %} {% load stat...

PYQT Error: one input ui-file must be specified错误

依据https://www.jianshu.com/p/8b992e47a0e4教程, 安装pycharm+PyQT+PyQt Designer+pyuic 可以生成UI,但是让.ui文件用右键生成.py文件一直报如下错误: Error: one input ui-file must be specified 找了,很多原因,其实只是因为.ui文件中间不能有空格,否则无法生成.py文件...

创建JPA工程时提示:at least one user library must be selected

问题描述:在Workspace中右键,new → JPA Project,选择JAP version为2.0。此时,向导中的Finish是灰色的,不能够点击完成。没办法,只好点击Next看看,一路Next下去看到如下图Figure 2.1所示这样一个问题:at least one user library must be selected。                        ...

redis中的hash扩容渐进式rehash过程

背景: redis字典(hash表)当数据越来越多的时候,就会发生扩容,也就是rehash 对比:java中的hashmap,当数据数量达到阈值的时候(0.75),就会发生rehash,hash表长度变为原来的二倍,将原hash表数据全部重新计算hash地址,重新分配位置,达到rehash目的 redis中的hash表采用的是渐进式hash的方式: 1、redis字典(hash表)底层有...

问答精选

How to get the sum of rows using a vector and the make the result in a column

I have a dataframe and i want to calculate the sum of variables present in a vector in every row and make the sum in other variable after i want the name of new variable created to be from the name of...

Call a custom class in zend framework

I have a very rough project that done partially in zend framework (not ZF2). The 'application', 'library' and 'public' folders are on the same root. Now i need to create a library 'Anil' in the 'libra...

Hide Some Of The Categories In Magento?

I want to hide some of the categories from magento home page. I have created some categories like New Arrivals, Special Offer Which I would like to show in some different way may be in left panel or r...

Reading an internal file in Android Studio

I am writing to an internal file in Android Studio The code lets me write lines of data split with commas. I am able to then go to another activity and read it all out at once. However I want to be ab...

Rails Acts_as_votable Gem Like/Unlike Buttons with Ajax

I'm new to Ruby On Rails, I used the acts_as_votable gem to create Like and Unlike Buttons to make Users like and unlike Posts but I can't make them change from Like to Unlike (and viceversa) and upda...

相关问题

相关文章

热门文章

推荐文章

相关标签

推荐问答