I created two tables using MYSQL, tblorder and tblitem.
CREATE TABLE `tblorder` (
`orderId` int NOT NULL,
`orderName` varchar(45) NOT NULL,
PRIMARY KEY (`orderId`)
CREATE TABLE `tblitem` (
`itemId` int NOT NULL,
`itemName` varchar(45) NOT NULL,
`itemUnit` varchar(5) NOT NULL,
`itemRate` double NOT NULL,
`orderRef` int NOT NULL,
PRIMARY KEY (`itemId`),
KEY `fk1_idx` (`orderRef`),
CONSTRAINT `fk1` FOREIGN KEY (`orderRef`) REFERENCES `tblorder` (`orderId`)
I tried to join the two tables using query below
SELECT orderId,orderName, itemName, itemUnit,itemRate
FROM tblitem
INNER JOIN tblorder on tblorder.orderId = tblitem.orderRef
Now result show like Image-01
How to remove duplicate values in orderId ,OrderName columns in result table?
Thanks to help me to solve this problem.
After joining tables is it possible to get output like below?
Answer for this question is available in below link. https://dba.stackexchange.com/questions/287746/join-two-tables-in-mysql-and-avoid-duplicate-values
SELECT CASE WHEN sortId = 1 THEN CAST(orderId AS CHAR(10)) ELSE '' END AS
orderId, CASE WHEN sortId = 1 THEN orderName ELSE '' END AS orderName,
itemName, itemUnit, itemRate
FROM
(
SELECT orderId, orderName, itemName, itemUnit, itemRate, ROW_NUMBER() OVER
(PARTITION BY orderId ORDER BY itemId) AS sortId
FROM
(
SELECT orderId, orderName, itemName, itemUnit, itemRate, itemId
FROM tblitem
INNER JOIN tblorder
on tblorder.orderId = tblitem.orderRef
) orderItems
) orderItemsSorted
ORDER BY orderItemsSorted.orderId, orderItemsSorted.sortId
Related
I have two tables as follows:
create table gift_certificate
(
id int auto_increment
primary key,
name varchar(64) not null,
description mediumtext not null,
price decimal default 0 not null,
duration int default 1 not null,
create_date datetime not null,
last_update_date datetime not null
)
and
create table tag
(
id int auto_increment
primary key,
name varchar(64) not null,
constraint tag_name_uindex
unique (name)
)
with a linking table:
create table gift_certificate__tag
(
certificate_id int not null,
tag_id int not null,
primary key (certificate_id, tag_id),
constraint gift_certificate__tag_gift_certificate_id_fk
foreign key (certificate_id) references gift_certificate (id),
constraint gift_certificate__tag_tag_id_fk
foreign key (tag_id) references tag (id)
)
I need to search for gift certificates by several tags (“and” condition). I only came up with a solution for one tag
select distinct gc.*, tag.* from gift_certificate gc
left outer join gift_certificate__tag joint on gc.id=joint.certificate_id
left outer join tag on joint.tag_id=tag.id
where tag.name='puppy'
order by gc.id desc;
Would be grateful for some support
You can aggregate the joint table by certificate and use HAVING to only keep certificates that have all the tags. Then select all matching certificates using an IN clause. For instance:
select *
from gift_certificate
where id in
(
select joint.certificate_id
from gift_certificate__tag joint
join tag on joint.tag_id=tag.id
group by joint.certificate_id
having max(case when tag.name = 'puppy' then 1 else 0 end) = 1
and max(case when tag.name = 'something' then 1 else 0 end) = 1
);
As true = 1 and false = 0 in MySQL, you can shorten the expression to
having max(tag.name = 'puppy')
if you find this readable. Or
having sum(tag.name = 'puppy') > 0
I have one to many table relationship :
one user for multiple event
one event for multiple event_attribute
Now, I group by userId and want to know how many for each event attribute ?
I am using group_concat like this:
group_concat(
concat(event_event_attribute.event_attr_id,
count( distinct event_event_attribute.value)
) group by event_attr_id)
)
group by userId
So here, I first group by userId, then group concat event-attribute, at least I hope to have :
(attr1, 10),(attr2, 30)....
all in one row.
But this does not work at all
Any suggestions?
To be more specific, this is the DB schema I am using:
CREATE TABLE `user` (
`id` int(11) NOT NULL,
`name` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id_UNIQUE` (`id`)
);
CREATE TABLE `event` (
`id` int(11) NOT NULL,
`name` varchar(45) DEFAULT NULL,
`user_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `event_attr` (
`id` int(11) NOT NULL,
`att_name` varchar(45) DEFAULT NULL,
`event_id` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`)
);
INSERT INTO `user` VALUES (1,'user1'),(2,'user2'),(3,'user3');
INSERT INTO `event` VALUES (1,'event1',1),(2,'event2',1),(3,'event3',1),(4,'event4',2),(5,'event5',2),(6,'event6',3);
INSERT INTO `event_attr` VALUES (1,'att1','1'),(2,'att2','1'),(3,'att3','1'),(4,'att1','2'),(5,'att2',NULL);
Now if I am running:
select u.id, group_concat(e.name)
from user u
join event e on u.id=e.user_id
group by u.id
I will get:
1 event1,event2,event3
2 event4,event6
3 event 6
That is fine. But one step forward, I need to know count for each event_attt for each user, such as:
1 evet_att1:3;event_att2:2
2 event_att3:1
Then it is not possible. Can I use just one query to get above expected response?
should be the inverse alias concat the aggreagted values and not aggregated the concat
select concat (group_concat(event_event_attribute.event_attr_id )
,' - ',
count( distinct event_event_attribute.value) )
from event_event_attribute
group by userid
Otherwise could be you need an subquery for obtain the count group by event_attr_id
select group_concat(
concat(event_attr_id), ',', count_value)
)
from t (
select user_id, event_event_attribute.event_attr_id, count( distinct event_event_attribute.value) count_value
from event_event_attribute
group by event_attr_id
) t
group by user_id
hi im having trouble doing a left join that outputs all customers who haven't made an order yet. im getting a conversion error and have tried using cast to convert it but it doesnt work. any help would be appreciated
here are my tables and data:`
create table Customers(
Cust_code varchar(2) primary key ,
[first_name] varchar(30) not null,
last_name varchar(30) not null,
address varchar(100) not null,
city varchar(35) not null)
create table Cust_Order(
order_no int ,
Cust_code varchar(2) not null,
order_date date not null,
meth_pmt varchar(30) not null,
constraint Ord_order_no_pk primary key(order_no),
constraint Cus_cust_code_fk foreign key(Cust_code) references Customers)
create table Product(
product_id int ,
product_name varchar(100) not null,
product_price decimal(8, 2) not null,
constraint Pro_product_id_pk primary key(product_id))
create table Order_Line(
order_no int ,
product_id int ,
qty int not null,
sale_price decimal(8,2) not null,
constraint Ord_order_no_product_id_pk primary key(order_no, product_id),
constraint Pro_product_id_fk foreign key(product_id) references Product)
insert into Customers (Cust_code, [first_name], last_name, address, city)
values('A1', 'Kath', 'Morgan','122 Lilain Street', 'Palmerston North'),
('A2','Mike','Smith','67 Golf Hill Drive','Wellington'),
('A3','Glen','Hoddle','San Quentin Ave','Palmerston North'),
('A4','Dan','Boone','Alamo Road','Wellington')
insert into Cust_Order (order_no, Cust_code, order_date, meth_payment)
values(1, 'A1','2014-01-16','CC'),
(2, 'A1','2014-02-16','CC'),
(3, 'A2','2014-01-16','CHEQUE'),
(4, 'A3','2014-03-17','CC')
insert into Product (product_id, product_name, product_price)
values(1, 'Network Card', 58.00),
(2, 'Motherboard', 150.00),
(3, 'Video Card', 232.00)
insert into Order_Line (order_no, product_id, qty, sale_price)
values(1,1,3,70.00),
(1,2,1,170.00),
(1,3,2,300.00),
(2,1,2,70.00),
(2,3,1,300.00),
(3,1,2,70.00),
(4,1,3,70.00)
my select statement using left join which should output the one customer who hasn't made an order
select first_name + last_name as 'Customers who have not made an order',
order_no from Customers as c
left join Cust_Order as o
on c.Cust_code = o.order_no
where order_no is null
Your join condition needs to match on the customer codes. Other than this, the logic of your query is correct, but MySQL doesn't use + for string concatenation, this is SQL Server syntax. Use the CONCAT function instead:
SELECT
CONCAT(c.first_name, ' ', c.last_name) AS `Customers who have not made an order`
FROM Customers AS c
LEFT JOIN Cust_Order AS o
ON c.Cust_code = o.Cust_code
WHERE o.Cust_code IS NULL;
The ANSI concatenation operator is ||, and you may also use it in MySQL if you set the appropriate mode:
SET sql_mode = PIPES_AS_CONCAT
If you must use a LEFT JOIN, try:
SELECT
CONCAT(C.first_name, ' ', C.last_name) AS 'Customers who have not made an order'
FROM Customers C LEFT JOIN Cust_Order CO
ON C.Cust_code=CO.Cust_code
GROUP BY Customer_FullName
HAVING COUNT(B.*)=0;
Or you can make use of EXISTS.
SELECT
CONCAT(C.first_name, ' ', C.last_name) AS 'Customers who have not made an order'
FROM Customers C
WHERE NOT EXISTS (SELECT NULL FROM Cust_Order CO WHERE C.Cust_code=CO.Cust_code);
See MySQL join made easy for insights on using joins.
I've been stuck on a MySQL query. The table is:
CREATE TABLE items_costs (
UPC varchar(15) NOT NULL,
SupplierID int(11) NOT NULL,
Current_as_of_Date datetime DEFAULT NULL,
Cost1 float DEFAULT NULL,
Cost2 float DEFAULT NULL,
Cost3 float DEFAULT NULL,
MSRP float DEFAULT NULL,
MAP float DEFAULT NULL,
Unique_Entry_Id datetime DEFAULT NULL,
PRIMARY KEY (UPC,SupplierID),
KEY SupplierID (SupplierID),
CONSTRAINT items_costs_ibfk_1 FOREIGN KEY (UPC) REFERENCES items (UPC),
CONSTRAINT items_costs_ibfk_2 FOREIGN KEY (SupplierID) REFERENCES suppliers (SupplierID)
) ENGINE=InnoDB DEFAULT CHARSET=utf8`
I'm getting the lowest of Cost1, Cost2, Cost3 for each item:
MIN(LEAST(IFNULL(ic.Cost3, ic.Cost1), IFNULL(ic.Cost2, ic.Cost1), ic.Cost1)) AS Cost
However, now I need to get the SupplierID associated with that particular Cost
I've tried:
SELECT
ic.UPC,
ic.SupplierID,
ic.Current_as_of_Date,
ic.Cost1 AS Cost,
ic.MSRP,
ic.MAP,
s.SupplierName,
s.Map_YN AS Supplier_MAP
FROM
items_costs AS ic
JOIN
suppliers AS s ON s.supplierId = ic.SupplierID
WHERE
(ic.upc , ic.Cost1) IN (SELECT
ic_min.UPC,
MIN(LEAST(IFNULL(ic_min.Cost3, ic_min.Cost1),
IFNULL(ic_min.Cost2, ic_min.Cost1),
ic_min.Cost1)) AS Cost
FROM
items_costs ic_min
GROUP BY ic_min.UPC))
...which gives the lowest Cost by UPC, as recommended in other threads. However, still getting duplicate UPC's, which should be unique.
What could I be doing wrong here?
Thanks a lot!
You could use DISTINCT
SELECT DISTINCT
ic.UPC,
ic.SupplierID,
ic.Current_as_of_Date,
ic.Cost1 AS Cost,
ic.MSRP,
ic.MAP,
s.SupplierName,
s.Map_YN AS Supplier_MAP
FROM items_costs AS ic
JOIN suppliers AS s ON s.supplierId = ic.SupplierID
WHERE (ic.upc , ic.Cost1) IN (
SELECT
ic_min.UPC,
MIN(LEAST(IFNULL(ic_min.Cost3, ic_min.Cost1),
IFNULL(ic_min.Cost2, ic_min.Cost1),
ic_min.Cost1)) AS Cost
FROM items_costs ic_min
GROUP BY ic_min.UPC))
Thanks for your help!
I found the answer here, and it seems to be a common question: https://dev.mysql.com/doc/refman/5.6/en/example-maximum-column-group-row.html
SELECT
ic1.upc,
ic1.supplierid,
ic1.MSRP,
ic1.MAP,
ROUND((LEAST(IFNULL(ic1.Cost3, ic1.Cost1),
IFNULL(ic1.Cost2, ic1.Cost1),
ic1.Cost1)),
2) AS Cost,
s.SupplierName,
s.Map_YN AS Supplier_MAP
FROM
items_costs AS ic1
JOIN
suppliers AS s ON s.supplierid = ic1.supplierid
WHERE
ic1.cost1 = (SELECT
MIN(ic2.cost1)
FROM
items_costs AS ic2
WHERE
ic1.upc = ic2.upc)
I'm trying to select mltiple rows from tow table :
first table is donor
CREATE TABLE donor(
donor_number INT NOT NULL AUTO_INCREMENT,
d_name VARCHAR(30) NOT NULL,
mobile_number INT NOT NULL,
blood_group VARCHAR(20) NULL,
dob DATE NOT NULL,
gender ENUM('male','female') NOT NULL,
govid INT(10) NOT NULL,
PRIMARY KEY (donor_number )
);
second table is blood_donation
CREATE TABLE blood_donation(
donor_number INT NOT NULL,
date_of_donate DATE NOT NULL,
blood_group VARCHAR(20) NULL,
serial_number INT(10) NOT NULL,
blood_component ENUM('wb','prcb') NOT NULL,
PRIMARY KEY (donor_number , date_of_donate ),
FOREIGN KEY (donor_number) REFERENCES donor(donor_number)
);
with this select statement:
SELECT
serial_number,
blood_group
FROM blood_donation
WHERE date_of_donate = '2012-07-18'
UNION ALL
SELECT
blood_group
FROM donor
WHERE donor.donor_number=blood_donation.donor_number;
but, I get error
SQL state 42S22: Unknown column 'blood_donation.donor_number' in 'where clause'
any idea????
Actually you should not be using UNION but JOIN :)
you query will look like this
SELECT
blood_donation.serial_number,
donor.blood_group
FROM
blood_donation ,
donor
WHERE donor.donor_number = blood_donation.donor_number AND date_of_donate = '2012-07-18' ;
A UNION is used to combine more than one result set into a single result set - and each result set must have the same set of columns.
What you need is a JOIN, which is how you link multiple tables together on foreign keys etc and would be something like this:
SELECT
serial_number,
blood_group
FROM blood_donation
INNER JOIN donor ON donor.donor_number=blood_donation.donor_number
WHERE date_of_donate = '2012-07-18'
SELECT
dd.serial_number,
dd.blood_group
FROM blood_donation dd
inner join
donor d
on d.donor_number=dd.donor_number
WHERE dd.date_of_donate = '2012-07-18';
UNION is not what exactly you need, Read some more about JOINS. Also please change the selection alias of columns as per the need. And you can use Left Join instead of Inner Join if you don't want a mandatory join condition on tables.