MS SQL Server Suggestion required - sql-server-2014

I need to find out the distinct entries in a table - order by the last transaction date in that table.
Here is the script to create the table and populate it with values
CREATE TABLE SM_TRANSACTION_HISTORY
([ID] [int] IDENTITY(100000001,1) NOT NULL,
[ProductNo] [nvarchar](10) NOT NULL,
[Container] [nvarchar](10) NOT NULL,
[QtyOnHand] [decimal]
)
INSERT INTO SM_TRANSACTION_HISTORY
([ProductNo],
[Container] ,
[QtyOnHand] )
VALUES
(
'PRd0001',
'Contr0001',
'8000'
)
INSERT INTO SM_TRANSACTION_HISTORY
([ProductNo],
[Container] ,
[QtyOnHand] )
VALUES
(
'PRd0001',
'Contr0001',
'7990'
)
INSERT INTO SM_TRANSACTION_HISTORY
([ProductNo],
[Container] ,
[QtyOnHand] )
VALUES
(
'PRd0001',
'Contr0001',
'7988'
)
INSERT INTO SM_TRANSACTION_HISTORY
([ProductNo],
[Container] ,
[QtyOnHand] )
VALUES
(
'PRd0002',
'Contr0002',
'5000'
)
INSERT INTO SM_TRANSACTION_HISTORY
([ProductNo],
[Container] ,
[QtyOnHand] )
VALUES
(
'PRd0002',
'Contr0002',
'4999'
)
INSERT INTO SM_TRANSACTION_HISTORY
([ProductNo],
[Container] ,
[QtyOnHand] )
VALUES
(
'PRd0002',
'Contr0002',
'4995'
)
INSERT INTO SM_TRANSACTION_HISTORY
([ProductNo],
[Container] ,
[QtyOnHand] )
VALUES
(
'PRd0003',
'Contr0003',
'3000'
)
INSERT INTO SM_TRANSACTION_HISTORY
([ProductNo],
[Container] ,
[QtyOnHand] )
VALUES
(
'PRd0003',
'Contr0003',
'2999'
)
INSERT INTO SM_TRANSACTION_HISTORY
([ProductNo],
[Container] ,
[QtyOnHand] )
VALUES
(
'PRd0001',
'Contr0001',
'7984'
)
INSERT INTO SM_TRANSACTION_HISTORY
([ProductNo],
[Container] ,
[QtyOnHand] )
VALUES
(
'PRd0001',
'Contr0001',
'7982'
)
INSERT INTO SM_TRANSACTION_HISTORY
([ProductNo],
[Container] ,
[QtyOnHand] )
VALUES
(
'PRd0003',
'Contr0003',
'2996'
)
The result I would need is like the following -
1 PRd0002
2 PRd0001
3 PRd0003
I tried the following
Select DISTINCT ProductNo from SM_TRANSACTION_HISTORY Order by ID
But I get the error -
Msg 145, Level 15, State 1, Line 122 ORDER BY items must appear in the
select list if SELECT DISTINCT is specified.
Not sure how to approach this. Any advice would be appreciated!

You cannot order by something that is not included in your select statement while using distinct. If you remove the order by, you get your 3 rows as expected. You could then order them by the productno if you wanted.
Select DISTINCT ProductNo
from #SM_TRANSACTION_HISTORY
or
Select DISTINCT ProductNo
from #SM_TRANSACTION_HISTORY
Order by ProductNo

Related

How to get next payment date on SQL

I have two tables project_payment and payment_schedule
CREATE TABLE project_payment (
`tenant_id` INTEGER,
`project_id` INTEGER,
`payment_date` datetime NOT NULL,
PRIMARY KEY(tenant_id,project_id,payment_date)
);
INSERT INTO project_payment
(`tenant_id`, `project_id`, `payment_date`)
VALUES
('1', '1', '2020-12-11 07:09:16'),
('1', '1', '2020-12-15 07:09:16');
CREATE TABLE payment_schedule (
`tenant_id` INTEGER not null ,
`project_id` INTEGER not null,
`schedule_date` datetime NOT NULL,
PRIMARY KEY(tenant_id,project_id,schedule_date)
);
INSERT INTO payment_schedule
(`tenant_id`, `project_id`, `schedule_date`)
VALUES
('1', '1', '2020-12-15 07:09:16'),
('1', '1', '2020-12-28 07:09:29'),
('1', '1', '2021-01-02 01:00:00');
Here I take last_payment_date, now i need to get the next payment schedule date
SELECT MAX(pp.payment_date) last_payment_date
FROM project_payment pp
JOIN payment_schedule ps
ON ps.tenant_id = pp.tenant_id
AND ps.project_id = pp.project_id;
I don't knw how to select the next date so I didn't write that code here..
I need to get next payment date from the schedule_date according to the current date(present day)
Expected output:
last_payment_date next_schedule_date
2020-12-15 07:09:16 2020-12-28 07:09:29
SELECT p.payment_date last_payment_date,
s.schedule_date next_schedule_date
FROM ( SELECT MAX(payment_date) payment_date
FROM project_payment ) p
JOIN payment_schedule s ON p.payment_date < s.schedule_date
ORDER BY s.schedule_date LIMIT 1

mysql query join two tables group by and get sum

It's about get sum product's quantity and name from joined orders grouped by date
I have two tables:
CREATE TABLE IF NOT EXISTS `orderproduct` (
`id` int(5) UNSIGNED NOT NULL AUTO_INCREMENT,
`quantity` int(3) NOT NULL,
`name` varchar(100) NOT NULL,
`fk_orders_id` int(3) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;
INSERT INTO `orderproduct` (`id`, `quantity`, `name`, `fk_orders_id`) VALUES
(1, 3, 'Boulgour de bléss', 1),
(2, 2, 'Casarecce d\'épeautre', 1),
(3, 1, 'Cerneaux de noix', 1),
(5, 2, 'Boulgour de bléss', 3),
(6, 2, 'Casarecce d\'épeautre', 3),
(7, 4, 'Casarecce d\'épeautre', 4),
(8, 4, 'Cerneaux de noix', 4);
INSERT INTO `orders` (`id`, `date`) VALUES
(1, '2020-06-29 17:02:11'),
(3, '2020-06-29 10:56:47'),
(4, '2020-06-30 11:20:24');
DROP TABLE IF EXISTS `orders`;
CREATE TABLE IF NOT EXISTS `orders` (
`id` int(3) NOT NULL AUTO_INCREMENT,
`date` timestamp NOT NULL DEFAULT current_timestamp(),
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
the exemple with the order grouped by date and make a sum from his same product quantity:
order 29/6
productsA quantity=1
productsB quantity=2
productsC quantity=3
order 29/6
productsA quantity=4
order 30/6
productsA quantity=1
productsB quantity=2
My knowledge of mysql is to basic here wath i have tried for the moment:
SELECT o.date, p.name, sum(p.quantity)
FROM `orders` o , `orderproduct` p
WHERE p.fk_orders_id = o.id
GROUP BY p.name
The sum of quantities are grouped by product but dont know how take care of grouping by orders date.
I tried also some sub query
(i know this not working because sub Q; return more than 1 row and shoul be used witn 'IN' but it is just for illustrate the idéé):
select o.date,p.name, (
SELECT sum(p.quantity)
FROM `orderproduct` p
GROUP BY p.name
)
FROM `orders` o , `orderproduct` p
WHERE p.fk_orders_id = o.id
Desired result could be:
order.date productname product.sumQuantity (name field)
2020-06-29 'Boulgour de bléss' 5, 'Casarecce d'épeautre' 4, 'Cerneaux de noix' 1
2020-06-30 'Casarecce d'épeautre' 4, 'Cerneaux de noix' 4,
thanks to #MdRanaHossain for the solution
SELECT date(o.date) date, p.name, sum(p.quantity)
from orderproduct p, orders o
where o.id = p.fk_orders_id
GROUP by date(o.date), p.name

I want to query sid="02" students learning the same course students sid;

CREATE TABLE `student` (
`sid` varchar(5) NOT NULL DEFAULT '',
`sname` varchar(10) NOT NULL,
`age` date DEFAULT NULL,
`sex` varchar(2) DEFAULT NULL,
PRIMARY KEY (`sid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `teacher` (
`tid` varchar(5) NOT NULL DEFAULT '',
`tname` varchar(10) NOT NULL,
PRIMARY KEY (`tid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `course` (
`cid` varchar(5) NOT NULL DEFAULT '',
`cname` varchar(10) NOT NULL,
`tid` varchar(5) DEFAULT NULL,
PRIMARY KEY (`cid`),
KEY `fk_tid` (`tid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `sc` (
`sid` varchar(5) NOT NULL DEFAULT '',
`cid` varchar(5) NOT NULL DEFAULT '',
`score` float DEFAULT NULL,
PRIMARY KEY (`sid`,`cid`),
KEY `fk_cid` (`cid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO student VALUES ('01' , 'student A' , '1990-01-01', 'M');
INSERT INTO student VALUES ('02' , 'student B' , '1990-12-21', 'M');
INSERT INTO student VALUES ('03' , 'student C' , '1990-05-20', 'M');
INSERT INTO student VALUES ('04' , 'student D' , '1990-08-06', 'M');
INSERT INTO student VALUES ('05' , 'student E' , '1991-12-01', 'FM');
INSERT INTO student VALUES ('06' , 'student F' , '1992-03-01', 'FM');
INSERT INTO student VALUES ('07' , 'student G' , '1989-07-01', 'FM');
INSERT INTO student VALUES ('08' , 'student H' , '1990-01-20', 'FM');
INSERT INTO teacher VALUES ('01' , 'teacher A');
INSERT INTO teacher VALUES ('02' , 'teacher B');
INSERT INTO teacher VALUES ('03' , 'teacher C');
INSERT INTO course VALUES ('01' , 'JAVA' , '01');
INSERT INTO course VALUES ('02' , 'Python' , '02');
INSERT INTO course VALUES ('03' , 'Mysql' , '03');
INSERT INTO course VALUES ('04' , 'PHP' , '01');
INSERT INTO sc VALUES ('01' , '01' , 80);
INSERT INTO sc VALUES ('01' , '02' , 90);
INSERT INTO sc VALUES ('01' , '03' , 99);
INSERT INTO sc VALUES ('01' , '04' , 88);
INSERT INTO sc VALUES ('02' , '01' , 70);
INSERT INTO sc VALUES ('02' , '02' , 60);
INSERT INTO sc VALUES ('02' , '03' , 80);
INSERT INTO sc VALUES ('03' , '01' , 80);
INSERT INTO sc VALUES ('03' , '02' , 80);
INSERT INTO sc VALUES ('03' , '03' , 80);
INSERT INTO sc VALUES ('04' , '01' , 50);
INSERT INTO sc VALUES ('04' , '02' , 30);
INSERT INTO sc VALUES ('04' , '03' , 20);
INSERT INTO sc VALUES ('05' , '01' , 76);
INSERT INTO sc VALUES ('05' , '02' , 87);
INSERT INTO sc VALUES ('06' , '01' , 31);
INSERT INTO sc VALUES ('06' , '03' , 34);
INSERT INTO sc VALUES ('07' , '02' , 89);
INSERT INTO sc VALUES ('07' , '03' , 98);
select * from enter code here
student where sid in (
select sid from sc
where cid in (select cid from sc where sid = '02')
group by sid
having count(*) = (select count(*) from sc where sid = '02')
)
i create mysql database with student table,course table,and sc table(selective courses) ,I want to query sid="02" students learning the same course students sid;
but the sql above is not right,"Why? How to fix it?"
is this what you want?
SELECT DISTINCT s2.*
FROM student
JOIN sc ON sc.sid = student.sid
JOIN sc AS sc2 ON sc2.cid = sc.cid
JOIN student AS s2 ON s2.sid = sc2.sid
WHERE student.sid = '02'
http://sqlfiddle.com/#!9/1d6a1/4
Also a suggestion is not to used strings as keys, it makes querying a lot slower when the amount of rows and comparisons grow bigger.

How to select row which has most distinct rows in second table - MySQL?

For a given Category, I am trying to find the Product item_name that has the most number of distinct locations recorded in Track_Record.
No matter what I try, I cant seem to figure out this query.
If someone wouldn't mind giving me a few hints, I would much appreciate it.
These are the relevant tables:
CREATE TABLE IF NOT EXISTS `Track_Record` (
`longitude` varchar(15) NOT NULL ,
`lattitude` varchar(15) NOT NULL ,
`datetime` DATETIME NOT NULL,
`EPC` varchar(200) NOT NULL ,
`ip` varchar(50) NOT NULL ,
PRIMARY KEY (ip, EPC, datetime),
FOREIGN KEY (EPC) REFERENCES Product(EPC) ON DELETE CASCADE,
FOREIGN KEY (ip) REFERENCES RFID_Reader(ip) ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS `Prod_Cat` (
`category_id` int(20) NOT NULL ,
`EPC` varchar(200) NOT NULL ,
PRIMARY KEY (category_id, EPC),
FOREIGN KEY (EPC) REFERENCES Product(EPC) ON DELETE CASCADE,
FOREIGN KEY (category_id) REFERENCES Category(category_id) ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS `Product` (
`EPC` varchar(200) NOT NULL ,
`expiry_date` DATE NOT NULL,
`production_date` DATE NOT NULL,
`prod_description` varchar(200) NOT NULL ,
`item_name` varchar(100) NOT NULL ,
`manufacturer_info` varchar(200) NOT NULL ,
`account_name` varchar(100) NOT NULL ,
`password` varchar(100) NOT NULL ,
PRIMARY KEY (EPC),
FOREIGN KEY (password, account_name) REFERENCES Owner(password, account_name) ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS `Category` (
`category_id` int(20) NOT NULL,
`name` varchar(100) NOT NULL ,
`description` varchar(200) NOT NULL,
`sub_category_id` int(20) NULL,
PRIMARY KEY (category_id),
FOREIGN KEY Category(sub_category_id) REFERENCES Category(category_id) ON DELETE CASCADE
);
And this is the data:
Category (name, description, category_id)
VALUES
('Technology', 'Technological Devices', 0),
('Dining Wear', 'Dinner plates and cups etc.', 1),
('Clothing', 'Stuff you wear', 2),
('Stationary', 'Office stuff!', 3);
Product (EPC, expiry_date, production_date, prod_description, item_name, manufacturer_info, password, account_name)
VALUES
('01.0000A89.00016F.000169DCD', '2019-01-09','2014-01-09', 'for eating off', 'Plate', 'man#company.com', 'a', 'John Smith'),
('02.0000A89.00016F.000169DCD', '2016-07-03','2013-01-23', 'for drinking from', 'Cup', 'somebody#aplaceinspace.com', 'c', 'John Mccane Manufacturer'),
('03.0000A89.00016F.000169DCD', '2018-09-23','2012-02-09', 'For playing games', 'Playstaion', 'nerdsrus#bamboozled.com', 'f', 'John Twitching'),
('04.0000A89.00016F.000169DCD', '2015-02-12','2014-03-11', 'For playing CDs', 'CD Player', 'whynotuseMP3#hopeless.com', 'd', 'John Dickson Retailer'),
('05.0000A89.00016F.000169DCD', '2017-06-11','2014-06-02', 'USB Storage Device', 'USB Stick', 'imustbeenglish#pommebugger.com', 'b', 'John Mitchal'),
('06.0000A89.00016F.000169DCD', '2019-02-08','2014-08-04', 'Wrap around your neck as a fashion statement', 'Boa Constrictor', 'byebye#shortofbreath.com', 'c', 'John Mccane Manufacturer');
Prod_Cat (category_id, EPC)
VALUES
('0', '03.0000A89.00016F.000169DCD'),
('0', '04.0000A89.00016F.000169DCD'),
('0', '05.0000A89.00016F.000169DCD'),
('1', '01.0000A89.00016F.000169DCD'),
('1', '02.0000A89.00016F.000169DCD'),
('2', '06.0000A89.00016F.000169DCD');
Track_Record (ip, longitude, lattitude, datetime, EPC)
VALUES
('000.111.222', '27.4667 S', '153.0333 E', '2014-11-05 18:56:46', '03.0000A89.00016F.000169DCD'),
('000.111.222', '27.4667 S', '153.0333 E', '2015-05-12 13:21:16', '03.0000A89.00016F.000169DCD'),
('555.666.777', '22.2783 N', '114.1747 E', '2012-07-19 12:22:16', '04.0000A89.00016F.000169DCD'),
('000.111.222', '27.4667 S', '153.0333 E', '2011-03-01 11:43:26', '03.0000A89.00016F.000169DCD'),
('555.666.777', '22.2783 N', '114.1747 E', '2014-09-02 18:53:14', '06.0000A89.00016F.000169DCD'),
('222.333.444', '59.3500 N', '18.0667 E', '2015-10-15 18:23:18', '04.0000A89.00016F.000169DCD'),
('333.444.555', '15.7833 S', '47.8667 W', '2015-02-22 19:53:16', '01.0000A89.00016F.000169DCD'),
('444.555.666', '51.5072 N', '0.1275 W', '2013-01-11 22:21:15', '04.0000A89.00016F.000169DCD');
Getting the count is a simple aggregation:
select pc.cat_id, p.item_name, count(*)
from track_record tr join
prod_category pc
on tr.epc = pc.epc join
product p
on p.epc = pc.epc
group by pc.cat_id, p.item_name;
Probably the easiest method to get the one with the largest count is to use the substring_index()/group_concat() trick:
select pc.cat_id, cnt,
substring_index(group_concat(item_name order by cnt desc), ',', 1) as most_common_item
from (select pc.cat_id, p.item_name, count(*) as cnt
from track_record tr join
prod_category pc
on tr.epc = pc.epc join
product p
on p.epc = pc.epc
group by pc.cat_id, p.item_name
) x
group by pc.cat_id;

Get records for each person's each day's min datetime

CREATE TABLE IF NOT EXISTS `accesscards` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`department` varchar(255) NOT NULL,
`name` varchar(255) NOT NULL,
`entrydates` datetime NOT NULL, PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
INSERT INTO `accesscards` (`id`, `department`, `name`, `entrydates`) VALUES
(1, 'test', 't1', '2013-12-06 16:10:00'),
(2, 'test', 't1', '2013-12-06 15:10:00'),
(3, 'test', 't1', '2013-12-07 15:11:00'),
(4, 'test', 't1', '2013-12-07 15:24:00'),
(5, 'test', 't2', '2013-12-06 16:10:00'),
(6, 'test', 't2', '2013-12-06 16:25:00'),
(7, 'test', 't2', '2013-12-07 15:59:00'),
(8, 'test', 't2', '2013-12-07 16:59:00');
Above is my query, I want to get records for a person for each day. And that record should have min datetime for the day. I need whole record for that date time
My expected output here
I tried using
SELECT id, MIN(entrydates) FROM accesscards WHERE 1=1 AND name!='' GROUP BY DATE(entrydates) ORDER BY id
but for 't1' I got id=1 and entrydates of first row.
Please help me out. If duplicate then provide link.
SELECT a1.*
FROM accesscards a1
JOIN (SELECT name, MIN(entrydates) mindate
FROM accesscards
WHERE name != ''
GROUP BY name, date(entrydates)) a2
ON a1.name = a2.name AND a1.entrydates = a2.mindate
DEMO
If you are using mysql : GROUP_CONCAT and SUBSTRING_INDEX
SELECT
DATE(entrydates) AS grouped_date,
GROUP_CONCAT(id ORDER BY entrydates ASC SEPARATOR ',') AS id_ordered_list,
SUBSTRING_INDEX(GROUP_CONCAT(id ORDER BY entrydates ASC), ',', 1) AS min_id_for_day
FROM
accesscards
WHERE
1=1 AND name!=''
GROUP BY
DATE(entrydates)
If you need other fields besides id to be shown, add this to you select :
SUBSTRING_INDEX(GROUP_CONCAT(YOUR_FIELDNAME_HERE ORDER BY entrydates ASC), ',', 1) AS min_YOUR_FIELDNAME_for_day
Play at http://sqlfiddle.com/#!2/a2671/13
After you updated your question with new data:
http://sqlfiddle.com/#!2/a2671/20
SELECT
DATE(entrydates) AS grouped_date,
SUBSTRING_INDEX(GROUP_CONCAT(id ORDER BY entrydates ASC), ',', 1) AS min_id_for_day,
department,
name,
SUBSTRING_INDEX(GROUP_CONCAT(entrydates ORDER BY entrydates ASC), ',', 1) AS min_entrydate_for_day
FROM
accesscards
WHERE
1=1 AND name!=''
GROUP BY
name,DATE(entrydates)
ORDER BY entrydates
Try this out this will surely help you
select id,department,name,entrydates from accesscards where entrydates in (select min(entrydates) from accesscards group by to_char(entrydates,'dd-Mon-yyyy')) order by id;