Say I have three tables as such:
Group Table
OGID
OGC
OGCD
56
300
TAS
81
TA
CAL
Structure Table
OSID
L1D
L2D
44
56
81
Contract
ContractID
44
Im giving the ContractID and I want to create a Table that has the follow:
ContractID
Structure L1D
Structure L2D
Group OGID
Group OGC
Group OGCD
Group OGID
Group OGC
Group OGCD
44
56
81
56
300
TAS
81
TA
CAL
What would be the best way to go about this in SQL?
There is also the problem that L2D can be null and anytime I try to make INNER JOIN statements to join the tables, the NULL ones are ignore.
SELECT
Contract.ContractID, Structure.L1D, Structure L2D, Group.OGID, Group.OGC, Group.OGID, Group2.OGID, Group2.OGC, Group2.OGID,
FROM
(
SELECT Structure.OSID, Structure.L1d, Group.OGID, Group.OGC, Group.OGCD
FROM Structure
INNER JOIN Group
ON (Structure.L1D = Group.OGID)
) T1
INNER JOIN
(
SELECT Structure.OSID, Structure.L1D, Group2.OGID, Group2.OGC, Group2.OGCD
FROM Structure
INNER JOIN Group2
ON (Structure.L2D = Group2.OGID)
) T2
ON (T1.OSID = T2.OSID OR T2.OSID = NULL)
See DBFIDDLE
SELECT
s.OSID,
s.L1D,
s.L2D,
g1.OGID,
g1.OGC,
g1.OGCSD,
g2.OGID,
g2.OGC,
g2.OGCSD
FROM structure s
LEFT JOIN `group` g1 ON g1.OGID = s.L1D
LEFT JOIN `group` g2 ON g2.OGID = s.L2D
The DBFIDDLE also shows what happens when L2D has the value NULL.
P.S. Generally you should not use, or at least try to avoid, Reserved Words as table names, like GROUP.
Related
hi guys i have a data from sql like
UserID UserInfo ImageName Point
159 Ozan Işık 1575972330250.jpeg 32
558 Mert Malaveş 1578248740672.jpeg 36
68 Egemen Yılmaz 1573696212462.jpeg 82
558 Mert Malaveş 1578248740678.jpeg 36
Here is my sql
SELECT DISTINCT Users.UserID,Users.UserInfo,BestPracticeParticipant.ImageName ,BestPracticeParticipant.Point
FROM BestPracticeParticipant
JOIN Users on Users.UserID=BestPracticeParticipant.UserID
WHERE BestPracticeParticipant.BestPracticeID=1
But i need to data like this
UserID UserInfo ImageName Point
159 Ozan Işık 1575972330250.jpeg 32
558 Mert Malaveş 1578248740672.jpeg 36
68 Egemen Yılmaz 1573696212462.jpeg 82
i need same UserID rows doesnt duplicate but i cant group by because of the other veriables from my sql.
Thank you.
If you want a random matching row, you can use row_number():
SELECT u.*
FROM (SELECT u.UserID, u.UserInfo, bpp.ImageName, bpp.Point,
ROW_NUMBER() OVER (PARTITION BY u.UserID ORDER BY rand()) as seqnum
FROM BestPracticeParticipant bpp JOIN
Users u
ON u.UserID = bpp.UserID
WHERE bpp.BestPracticeID = 1
) u
WHERE seqnum = 1;
Note: You can control which row you get by modifying the ROW_NUMBER().
EDIT: The above works on MySQL 8+. If you have an older version, then a unique id in the result set can be used to do what you want.
For instance, if ImageName is unique (for a given user):
SELECT u.UserID, u.UserInfo, bpp.ImageName, bpp.Point
FROM useres u JOIN
BestPracticeParticipant bpp
ON u.UserID = bpp.UserID
WHERE bpp.BestPracticeID = 1 AND
bpp.ImageName = (SELECT MAX(bpp2.ImageName)
FROM BestPracticeParticipant bpp2
WHERE bpp2.UserID = bpp.UserID AND
bpp2.BestPracticeID = 1
);
It seems your MySQL version doesn't support window functions. So from your sample data, You may try below query -
SELECT DISTINCT U.UserID,U.UserInfo,BPP.ImageName,BPP.Point
FROM (SELECT UserID, MIN(ImageName), Point
FROM BestPracticeParticipant
GROUP BY UserID, Point) BPP
JOIN Users U on U.UserID=BPP.UserID
WHERE BPP.BestPracticeID=1
I have a table leave_form which looks like:
type id reporting_id leave_bal from_date_id leave_from to_date_id leave_to number leave_for status applied_dates_id pendays
personal 99 6 10 1023 full day 1313 full day 10 personal yes 1026 null
I have separate table for dates, so that I can refer these dates into leave_form. My leave_date table looks like:
date_id(AI) dates(UK)
1025 2016-02-18
1301 2016-02-20
1218 2016-02-16
This date_id I have inserted into from_date_id, to_date_id, applied_dates_id columns in leave_form table i.e. all dates are inserted into leave_date table and from this table I am only referring the date_id into leave_form table.
There is also a table that keeps the emp_code and emp_name. My personal table is:
id(AI) emp_code(PK) emp_name
99 K0209 Nijo
When I am trying to fetch the date for from_date_id, to_date_id, applied_dates_id column from leave_form table I don't get any values.
My query for fetching the dates is:
select g.type, a.emp_code, h.rm_id, h.rm_name, g.leave_bal, i1.dates as from_date,
g.leave_from, i2.dates as to_date, g.leave_to, g.number, g.leave_for, g.status,
i3.dates as applied_date, g.pendays
from personal a
inner join leave_form g
on a.id = g.id
inner join inform_to_rm h
on h.reporting_id = g.reporting_id
inner join leave_dates i1
on i1.dates = g.from_date_id
inner join leave_dates i2
on i2.dates = g.to_date_id
inner join leave_dates i3
on i3.dates = g.applied_dates_id
where a.emp_code = 'K0209';
It shows me result like:
type, emp_code, rm_id, rm_name, leave_bal, from_date, leave_from, to_date, leave_to, number, leave_for, status, applied_date, pendays
i.e no data gets returned when I am executing this query.
I would agree with one of the comments to the question. I would recommend referencing the date directly in the leave_form table instead of a FK to a table with dates. But back to the question. You haven't described all of your tables completely, so it is possible that there are multiple problems that I can't see, however, there is definitely one problem.
Your query joins on
inner join leave_dates i1
on i1.dates = g.from_date_id
inner join leave_dates i2
on i2.dates = g.to_date_id
inner join leave_dates i3
on i3.dates = g.applied_dates_id
This is incorrect. leave_dates.dates is the actual DATE, while the columns that you are joining on (leave_form.from_date_id, leave_form.to_date_id, leave_form.applied_dates_id) are foreign key references.
For example, 1023 does not equal 2016-02-18 so you get no match. Replacing the above query-snippet with the following would correct this particular problem.
inner join leave_dates i1
on i1.date_id = g.from_date_id
inner join leave_dates i2
on i2.date_id = g.to_date_id
inner join leave_dates i3
on i3.date_id = g.applied_dates_id
I want to extract all the rows from a database table, where the rows cross-reference each other.
My table contains 2 rows: ref1 & ref2
Table example:
ID ref1 ref2
01 23 83
02 77 55
03 83 23
04 13 45
In this case, I want my query to return only rows 01 and 03, because they cross-reference each other.
Is this possible using a single query, or will I need to iterate the entire table manually?
I'm using MySQL.
A simple JOIN can do that in a straight forward manner;
SELECT DISTINCT a.*
FROM mytable a
JOIN mytable b
ON a.ref1 = b.ref2 AND a.ref2 = b.ref1;
An SQLfiddle to test with.
select
*
from
tbl t1
where
exists (
select
'x'
from
tbl t2
where
t1.ref1 = t2.ref2 and
t1.ref2 = t2.ref1
)
Let me first present the solution in a context of a table that is meant for representing trees but faces this issue (resulting in a cross reference that is not anymore part of the tree).
Note: If your root tree record(s) reference themselves then you need to filter them out ( a.id!=b.id) as below, to keep only cross-referencing records.
-- case of a tree(s)
select
a.id currentId,
b.id parentId,
b.parent_id grandParentId
from my_table a
join my_table b on
a.parent_id=b.id
and b.parent_id=a.id
and a.id!=b.id;
Now in your case, the above query can be written as (Again considering that records referencing themselves are allowed we add and a.ref1!=b.ref2):
-- case of a graph(s)
select
a.ref1 theCurrent,
b.ref1 theRef,
b.ref2 theRefsRef
from my_table a
join my_table b on
a.ref2=b.ref1
and b.ref2=a.ref1
and a.ref1!=b.ref2;
I have this data in a table, for instance,
id name parent parent_id
1 add self 100
2 manage null 100
3 add 10 200
4 manage null 200
5 add 20 300
6 manage null 300
How can I left join or inner join this table itself so I get this result below?
id name parent
2 manage self
4 manage 10
6 manage 20
As you can I that I just want to query the row with the keyword of 'manage' but I want the column parent's data in add's row as the as in manage's row in the result.
Is it possible?
EDIT:
the simplified version of my actual table - system,
system_id parent_id type function_name name main_parent make_accessible sort
31 30 left main Main NULL 0 1
32 31 left page_main_add Add self 0 1
33 31 left page_main_manage Manage NULL 0 2
my actual query and it is quite messy already...
SELECT
a.system_id,
a.main_parent,
b.name,
b.make_accessible,
b.sort
FROM system AS a
INNER JOIN -- self --
(
SELECT system_id, name, make_accessible, sort
FROM system AS s2
LEFT JOIN -- search --
(
SELECT system_id AS parent_id
FROM system AS s1
WHERE s1.function_name = 'page'
) AS s1
ON s1.parent_id = s2.parent_id
WHERE s2.parent_id = s1.parent_id
AND s2.system_id != s1.parent_id
ORDER BY s2.sort ASC
) b
ON b.system_id = a.parent_id
WHERE a.function_name LIKE '%manage%'
ORDER BY b.sort ASC
result I get currently,
system_id main_parent name make_accessible sort
33 NULL Main 0 1
but I am after this,
system_id main_parent name make_accessible sort
33 self Main 0 1
You just need to reference the table twice:
select t1.id, t1.name, t2.id, t2.name
from TableA t1
inner join TableA t2
on t1.parent_id = t2.Id
Replace inner with left join if you want to see roots in the list.
UPDATE:
I misread your question. It seems to me that you always have two rows, manage one and add one. To get to "Add" from manage:
select system.*, (select parent
from system s2
where s2.parent_id = system.parent_id
and s2.name = 'add')
AS parent
from system
where name = 'manage'
Or, you might split the table into two derived tables and join them by parent_id:
select *
from system
inner join
(
select * from system where name = 'add'
) s2
on system.parent_id = s2.parent_id
where system.name = 'manage'
This will allow you to use all the columns from s2.
Your data does not abide to a child-parent hierarchical structure. For example, your column parent holds the value 10, which is not the value of any id, so a child-parent association is not possible.
In other words, there's nothing that relates the record 2,manage,null to the record 1,add,self, or the record 4,manage,null to 3,add,10, as you intend to do in your query.
To represent hierarchical data, you usually need a table that has a foreign key referencing it's own primary key. So your column parent must reference the column id, then you can express a child-parent relationship between manage and add. Currently, that's not possible.
UPDATED: Joining by parent_id, try:
select m.id, m.name, a.parent
from myTable m
join myTable a on m.parent_id = a.parent_id and a.name = 'add'
where m.name = 'manage'
Change the inner join to a left join if there may not be a corresponding add row.
I am trying to use TWICE inner join statement to get reference values in the same detail table.
Master table: bags_tbl
ID ... bagA bagB
1 ... 121 122
2 ... 123 124
3 ... 125 126
Detail table: fruit_tbl
ID ... fruit ...
121 strawbery
122 apple
123 orange
124 raspberry
125 pear
126 pineapple
SELECT
bags_tbl.ID,
bags_tbl.A,
bags_tbl.B,
fruit_tbl.fruit AS bagA_fruit,
fruit_tbl.fruit AS bagB_fruit
FROM
bags_tbl
Inner Join fruit_tbl ON bags_tbl.bagA = fruit_tbl.fruit
Inner Join fruit_tbl ON bags_tbl.bagB = fruit_tbl.fruit
this throw error : no unique table/alias...
How to make SQL statement to get text representation of master table?
thankx a lot
SELECT
bags_tbl.ID,
bags_tbl.A,
bags_tbl.B,
A.fruit AS bagA_fruit,
B.fruit AS bagB_fruit
FROM bags_tbl
Inner Join fruit_tbl A ON bags_tbl.bagA = A.id
Inner Join fruit_tbl B ON bags_tbl.bagB = B.id
Try this. You need to grant a unique alias to each join so SQL knows which one you're referencing in the SELECT clause.
SELECT
bags_tbl.ID,
bags_tbl.A,
bags_tbl.B,
fruitA.fruit AS bagA_fruit,
fruitB.fruit AS bagB_fruit
FROM
bags_tbl
JOIN fruit_tbl fruitA ON bags_tbl.bagA = fruitA.id
JOIN fruit_tbl fruitB ON bags_tbl.bagB = fruitB.id