i have 3 table with name city and state and project
city
id_city | name_city
1 | JED
2 | RYD
3 | DMM
state
column city_id foreign key with city.city_id
id_state | name_state | city_id
1 | JED 1 | 1(JED)
2 | RYD 1 | 2(RYD)
3 | RYD 2 | 2(RYD)
project
column state_from_city_id_table_state foreign key with state .city_id
id_project | city_id | state_from_city_id_table_state
1 | 1 | 1(JED)>> (JED1) question here
2 | 2 | 2(RYD)>> (RYD 1 or2) question here
now question is i selected city_id from project table ... like 1 and i just want see city_id from state table number 1 without number 2 in state_id from table project
like this JED > JED1 only i don't wanna see RYD1 and RYD2
SELECT ct.*, st.*, pr.* FROM `city` ct LEFT JOIN `state` st ON ct.`id_city` = st.`state_id` LEFT JOIN `project` pr ON ct.`id_city` = pr.`city_id`
Related
I want to get records from array of one table which are not present in another table column. Following are the tables;
automobile_data
-----------------------------------------------
veh_id | vehicle_types
--------+---------------------------------------
1 | {"byd_tang","laferrari"}
2 | {"sonata","jaguarxf"}
3 | {"swift","teslax","mirai"}
4 | {"volt","viper"}
5 | {"ferrariff","bmwi8"}
------------------------------------------------
vehicle
-----------------------------------------------
vehicle_name | id
------------------------------------------------
byd_tang | 1
laferrari | 1
sonata | 2
jaguarxf | 2
swift | 3
teslax | 3
------------------------------------------------
Require following output;
-----------------------------------------------
vehicle_name | veh_id
------------------------------------------------
mirai | 3
volt | 4
viper | 4
ferrariff | 5
bmwi8 | 5
------------------------------------------------
This can be done using first unnest the array from table automobile_data and then find name which is not exists in vehicle table;
SELECT c.vehicle_name, c.veh_id
FROM
(
SELECT veh_id, unnest("vehicle_types") as vehicle_name
FROM automobile_data
) c where not exists
( SELECT FROM vehicle
where vehicle_name = c.vehicle_name);
I have two tables in a reporting database, one for orders, and one for order items. Each order can have multiple order items, along with a quantity for each:
Orders
+----------+---------+
| order_id | email |
+----------+---------+
| 1 | 1#1.com |
+----------+---------+
| 2 | 2#2.com |
+----------+---------+
| 3 | 3#3.com |
+----------+---------+
Order Items
+---------------+----------+----------+--------------+
| order_item_id | order_id | quantity | product_name |
+---------------+----------+----------+--------------+
| 1 | 1 | 1 | Tee Shirt |
+---------------+----------+----------+--------------+
| 2 | 1 | 3 | Jeans |
+---------------+----------+----------+--------------+
| 3 | 1 | 1 | Hat |
+---------------+----------+----------+--------------+
| 4 | 2 | 2 | Tee Shirt |
+---------------+----------+----------+--------------+
| 5 | 3 | 3 | Tee Shirt |
+---------------+----------+----------+--------------+
| 6 | 3 | 1 | Jeans |
+---------------+----------+----------+--------------+
For reporting purposes, I'd love to denormalise this data into a separate PostgreSQL view (or just run a query) that turns the data above into something like this:
+----------+---------+-----------+-------+-----+
| order_id | email | Tee Shirt | Jeans | Hat |
+----------+---------+-----------+-------+-----+
| 1 | 1#1.com | 1 | 3 | 1 |
+----------+---------+-----------+-------+-----+
| 2 | 2#2.com | 2 | 0 | 0 |
+----------+---------+-----------+-------+-----+
| 3 | 3#3.com | 3 | 1 | 0 |
+----------+---------+-----------+-------+-----+
ie, it's a sum of the quantity of each item within the order with the product name; and the product names set as the column titles. Do I need to use something like crosstab to do this, or is there a clever way using subqueries even if I don't know the list of distinct product names at before the query runs.
This is one possible answer:
create table orders
(
orders_id int PRIMARY KEY,
email text NOT NULL
);
create table orders_items
(
order_item_id int PRIMARY KEY,
orders_id int REFERENCES orders(orders_id) NOT NULL,
quantity int NOT NULL,
product_name text NOT NULL
);
insert into orders VALUES (1, '1#1.com');
insert into orders VALUES (2, '2#2.com');
insert into orders VALUES (3, '3#3.com');
insert into orders_items VALUES (1,1,1,'T-Shirt');
insert into orders_items VALUES (2,1,3,'Jeans');
insert into orders_items VALUES (3,1,1,'Hat');
insert into orders_items VALUES (4,2,2,'T-Shirt');
insert into orders_items VALUES (5,3,3,'T-Shirt');
insert into orders_items VALUES (6,3,1,'Jeans');
select
orders.orders_id,
email,
COALESCE(tshirt.quantity, 0) as "T-Shirts",
COALESCE(jeans.quantity,0) as "Jeans",
COALESCE(hat.quantity, 0) as "Hats"
from
orders
left join (select orders_id, quantity from orders_items where product_name = 'T-Shirt')
as tshirt ON (tshirt.orders_id = orders.orders_id)
left join (select orders_id, quantity from orders_items where product_name = 'Jeans')
as jeans ON (jeans.orders_id = orders.orders_id)
left join (select orders_id, quantity from orders_items where product_name = 'Hat')
as hat ON (hat.orders_id = orders.orders_id)
;
Tested with postgresql. Result:
orders_id | email | T-Shirts | Jeans | Hats
-----------+---------+----------+-------+------
1 | 1#1.com | 1 | 3 | 1
2 | 2#2.com | 2 | 0 | 0
3 | 3#3.com | 3 | 1 | 0
(3 rows)
Based on your comment, you can try to use tablefunc like this:
CREATE EXTENSION tablefunc;
SELECT * FROM crosstab
(
'SELECT orders_id, product_name, quantity FROM orders_items ORDER BY 1',
'SELECT DISTINCT product_name FROM orders_items ORDER BY 1'
)
AS
(
orders_id text,
TShirt text,
Jeans text,
Hat text
);
But I think you are thinking the wrong way about SQL. You usually know which rows you want and have to tell it SQL. "Rotating tables" 90 degrees is not part of SQL and should be avoided.
Please, can someone help me with what is possibly a simple query?
We have two tables with below structure.
Customer table:
+----+-----------+
| id | name |
+----+-----------+
| 1 | customer1 |
| 2 | customer2 |
| 3 | customer3 |
+----+-----------+
Customer role mapping table:
+-------------+-----------------+
| customer_id | customerRole_id |
+-------------+-----------------+
| 1 | 1 |
| 1 | 2 |
| 2 | 1 |
| 3 | 1 |
| 4 | 1 |
| 5 | 1 |
+-------------+-----------------+
I want to select customers with role id 1 only NOT with role id 1 AND 2.
So, in this case, it would be customer id 2,3,4 & 5. ignoring 1 as it has multiple roles.
Is there a simple query to do this?
Many thanks, for any help offered.
Hmmm, there are several ways to do this.
select c.*
from customers c
where exists (select 1 from mapping m where m.customerid = c.id and m.role = 1) and
not exists (select 1 from mapping m where m.customerid = c.id and m.role <> 1);
If you just want the customer id, a perhaps simpler version is:
select customerid
from mapping
group by customerid
having min(role) = 1 and max(role) = 1;
This solution assumes that role is never NULL.
I have a table "temp"
author | title | bibkey | Data
-----------------------------------
John | JsPaper | John2008 | 65
Kate | KsPaper | | 60
| | Data2015 | 80
From this I want to produce two tables, a 'sample_table' and a 'ref_table' like so:
sample_table:
sample_id|ref_id| data
--------------------------
1 | 1 | 65
2 | 2 | 60
3 | 3 | 80
ref_table:
ref_id | author | title | bibkey
--------------------------------------
1 | John | JsPaper | John2008
2 | Kate | KsPaper |
3 | | | Data2015
I've created both tables
CREATE TABLE ref_table ( CREATE TABLE sample_table (
ref_id serial PRIMARY KEY, sample_id serial PRIMARY KEY,
author text, ref_id integer REFERENCES ref_table(ref_id),
title text, data numeric
bibkey text );
);
And inserted the unique author,title,bibkey rows into the reference table as above. What I want to do now is do the join for the sample_table to get the ref_id's. For my insert statement i currently have:
INSERT INTO sample_table (
ref_id,data
)
SELECT ref.ref_id, t.data
FROM
temp t
LEFT JOIN
ref_table ref ON COALESCE(ref.author,'00000') = COALESCE(t.author,'00000')
AND COALESCE(ref.title,'00000') = COALESCE(t.title,'00000')
AND COALESCE(ref.bibkey,'00000') = COALESCE(t.bibkey,'00000');
However i really want to have a conditional statement in the join, rather than all 3 like I have:
IF a bibkey exists for that row, I know it is unique, and join only on that.
If bibkey is NULL, then join on both author and title for the unique pair, and not bibkey.
Is this possible?
Hi I have doubt in sql server
Trantable:
empid | deptid | Projectname | Transactionid
1 |10 | test | 1
2 |11 | test1 | 2
2 |10 | jai | 3
2nd table: dimemp ....> here dimemp is scdtype2 dimension.its all ready done
empkey | empid | ename | flag
1 | 1 | a | 1
2 | 2 | b | 1
3 | -1 | na | 1
3rd table: dimdept------>here dimdept is scdtype2 dimension.implementaion allready done.
deptkey | deptid | deptname | flag
1 | 10 | hr | 1
2 | 11 | ceo | 1
3 | -1 | NA | 1
Here I want load trantable data into facttran table with corresponding keys. here transactionid is unique column
to identiy unique record.
Facttran table structure look like below and factran we need to maintain scd type1 data.
empkey | deptkey | projectname |transactionid
I tried like below query
merge into facttran target
using (select ISNULL(a.empkey, (select empkey from Dimemp where empid = -1)) empkey,ISNULL(b.deptkey, (select deptkey from dimdept where deptid = -1)) deptkey, c.projectname, c.transactionid
from trantable c
left join dimemp a on a.empid=c.empid and a.flag=1
left join dimdept b on b.deptid=c.deptid and b.flag=1)source
on target.transactionid=source.transactionid
when not matched
then insert ([deptkey],[empkey],[projectname],[transactionid])
values(source.deptkey,source.empkey,source.projectname,source.transactionid)
when matched
then update set target.empkey=source.empkey ,
target.deptkey=source.deptkey,
target.projectname=source.projectname,
target.transactionid=source.transactionid ;
then I got output like below
Table :facttran
empkey | deptkey | projectname |transactionid
1 | 1 | test | 1
2 | 2 | test1 | 2
2 | 1 | Jai | 3
upto now its working fine.
2nd day in my trantable few records updated and few records insert in sourc trantable.based on below table data I want update in facttable with corresponding key.
2nd table: dimemp ....> here dimemp is scdtype2 dimension
empkey | empid | ename | flag
1 | 10 | a | 0
2 | 11 | b | 1
3 | -1 | na | 1
4 | 10 | aaa | 1
3rd table: dimdept------>here dimdept is scdtype2 dimension.implementaion allready done.
deptkey | deptid | deptname | flag
1 | 10 | hr | 0
2 | 20 | ceo | 1
3 | -1 | NA | 1
4 | 10 |hrdept | 1
Trantable:
empid | deptid | Projectname | Transactionid
1 |11 | test | 1 ------record updated in source side here deptid changed from 10 to 11
1 |11 | test123 | 2 -------Here empid changed from empid 2 to 1 and projectname changed test1 to test123
2 |10 | jai | 3 ------here no records are not changed
1 |10 | cod | 4 ----------new rocrd is came
based on above trantable.I want facttran table data look like below.
Table :facttran
empkey | deptkey | projectname |transactionid
1 | 2 | test | 1
1 | 2 | test123 | 2
2 | 1 | Jai | 3
4 | 10 | cod | 4
when I ran 2nd time with same query.I am not able get to expected result.
here mainily source trantable related transactioni id is exist or not in facttran table .if not exist then we need to insert correspondig dimensionkeys with lates flaf=1
values.if we found transactionid exist in fact table then we need to updated existing dimension corresonding key.
suppose if we take transactionid=1 records here only chnaged deptid not empid that time we donot need update empid corresponding lates flag=1 corresondingkey
we need check exisig transaction id is updated each dimension need to check exist or not if not exist latest flag=1 related corresponding key.
if exist we donot need to updated that one.if new reocrds came then we need to insert with latest flag=1 corresponding keys in factran table.
please tell me how to write query to achive this task in sql server.