I am having 2 tables :
1.internal_employee_master
id employee_name unique_id
1 Noah ABCD
2 Liam ABCD
3 William ABCD
4 Benjamin ABCD
5 Jacob EFGH
2.external_employee_master
id name unique_id
1 Elijah ABCD
2 Ethan ABCD
3 Alexander EFGH
I am using UNION query to get both tables data into single table and display this data into html table.
select id
, employee_name
, unique_id
from internal_employee_master
where unique_id = 'ABCD'
union
select id
, employee_name
, unique_id
from external_employee_master
where unique_id = 'ABCD'
I want to store payslips of both employees into single table.
I have one table payslips with emp_id and emp_type columns.
I am storing data into payslips data like:
id pay_slip emp_id emp_type
1 Noah_payslip.pdf 1 internal
2 Liam_payslip.pdf 2 internal
3 Lia_payslip.pdf 1 External
as you can see in above table i am storing emp_id and emp_type of
both the tables in single columns each.
Now, i dont undestand how to split data of internal employee and
external employee from pay_slip table and show data in html table.
Currently, i am writing below sql joins to get employee_names of
internal and external employee tables but it doesnt work for me.
$id = $_GET['id];
SELECT ps.id,ps.pdf,ps.emp_id,ps.emp_type,external_employee.name as comemp,
internal_employee.comp_empl_name as comemp
FROM pay_slip as ps
INNER JOIN internal_employee_master as internal_employee ON internal_employee.comp_trad_id = ps.trade_id
INNER JOIN external_employee_master as external_employee ON external_employee.trad_id = ps.trade_id
where ps.is_deleted = 1 AND ps.id = '".$id."'"
Please help me to join query to get name and employee_name with respect to emp_type form pay_slip table.
How about using UNION again?
SELECT
ps.id,
ps.pdf,
ps.emp_id,
ps.emp_type,
external_employee.name AS comemp,
internal_employee.comp_empl_name AS comemp
FROM
pay_slip AS ps
INNER JOIN
internal_employee_master AS internal_employee ON internal_employee.comp_trad_id = ps.trade_id
WHERE
ps.is_deleted = 1 AND ps.id = '".$id."'
AND ps.type = 'internal'
UNION ALL
SELECT
ps.id,
ps.pdf,
ps.emp_id,
ps.emp_type,
external_employee.name AS comemp,
internal_employee.comp_empl_name AS comemp
FROM
pay_slip AS ps
INNER JOIN
external_employee_master AS external_employee ON external_employee.trad_id = ps.trade_id
WHERE
ps.is_deleted = 1 AND ps.id = '".$id."'
AND ps.type = 'external'
You could try this
SELECT ps.id, ps.pay_slip, ps.emp_type, COALESCE(i.employee_name, e.name) AS name
FROM payslips ps
LEFT JOIN internal_employee_master i ON i.id = ps.emp_id AND ps.emp_type = 'internal'
LEFT JOIN external_employee_master e ON e.id = ps.emp_id AND ps.emp_type = 'External'
AND ps.id = :ID
You can see this in action here http://sqlfiddle.com/#!9/53a195/7/0
I would mention that there are a number of issues in your included tables and queries. For example, irregular column names between tables (name vs. employee_name), you've missed the is_deleted column from your example schema, and you have capitalised and non-capitalised values in the emp_type column which is confusing.
Related
I would like to append the results of 2 queries into one result set.
SELECT n.member_no, n.surname, n.first_name
FROM `names` AS n
WHERE member_no = '1003';
SELECT s.registration
FROM `system` AS s
WHERE s.RECNUM = 1;
This must return one record with data from the names table plus data from the system (one record) table
Member_no | surname | first_name | registration
--------------------------------------------------
1003 | Brown | Peter | My registration
You can use CrossJoin:
SELECT n.member_no, n.surname, n.first_name, s.registration
FROM names AS n
CROSS JOIN system s
WHERE n.member_no = '1003' and s.RECNUM = 1;
we can correlate your registration and name tables based on row_number(). You may want to try below query.
SELECT rn.member_no, rn.surname, n.first_name, s.registration
FROM
(SELECT member_no, surname, first_name, row_number() over (order by member_no) rn
FROM `names`) n
LEFT JOIN
(SELECT row_number() over (order by RECNUM) rn, registration
FROM `system`) s on s.rn = n.rn
WHERE n.member_no = '1003'
Try this one.
SELECT DISTINCT n.member_no, n.surname, n.first_name,s.registration
FROM `names` AS n, `system` AS s
WHERE s.RECNUM = 1 AND member_no = '1003';
I have two tables like these:
Table "users":
user_id | source
----------------
1 | 2
2 | 2
3 | 3
4 | 0
Table "sources":
source_id | name
----------------
1 | "one"
2 | "two"
3 | "three"
4 | "four"
Now I need to SELECT (*) FROM source and additionally COUNT "users" that have this source, BUT if there is an additional filter(requests by PHP mysqli), then additionally sort "sources" table by its users count.
What is the best way to do so, and is it possible to do in one statement?
--------------Added editing----------
The first part(SELECT with count from another table) I'm doing this way:
SELECT
id, name
(select count(*) from users where source = sources.id) as sourceUsersCount
FROM sources
And now, how to order this list by users count in each source?
Please check the below query if this is what you need.
select s.*,a.c from sources s
left join
(select count(*) as c,source as src
from user u join sources s
on s.source_id = u.source group by u.source) a
on s.source_id = a.src;
Count the number of users:
SELECT sources.*, COUNT(users.user_id) FROM sources
LEFT JOIN users ON users.source_id = sources.source_id
GROUP BY sources.source_id;
I assume by filters you mean the WHERE clause:
SELECT sources.*, COUNT(users.user_id) FROM sources
LEFT JOIN users ON users.source_id = sources.source_id
WHERE sources.source_id = 2
GROUP BY sources.source_id;
And you can always attach an ORDER BY on the end for sorting:
SELECT sources.*, COUNT(users.user_id) FROM sources
LEFT JOIN users ON users.source_id = sources.source_id
GROUP BY sources.source_id
ORDER BY sources.source_id DESC;
Achieved it by doing so:
SELECT
sources.*,
count(users.source) as sourceUsersCount
FROM sources
LEFT JOIN users ON sources.id = users.source
//In case of additional filters
WHERE
id != 0 AND (name LIKE %?% OR id LIKE %?%)
//\\
GROUP BY sources.id
//In case of sorting by "users" count
ORDER BY sourceUsersCount ASC
//\\
Is it the best way, or maybe there are some faster variants?
id parent_id child_id
1 1 1
2 2 2
3 2 2
4 1 1
I have a table from which i need to get the common values from data when i query it with id... for eg if id=2 and id=3 then return
id parent_id
2 2
3 2
i have tried this after hunting a lot through various examples :
SELECT ta.user_id,ta.interest_parent_id,ta.interest_child_id
FROM user_interest ta
WHERE ta.user_id=2 AND
(SELECT COUNT(*) FROM user_interest tb
WHERE ta.interest_parent_id=tb.interest_parent_id
AND tb.user_id=3 )>1
but it responds with only:
id parent_id
2 2
any help :( im using a mysql database with php/codeigniter to do the scripting
You can give it a try:
SELECT
tOne.id,
tOne.parent_id
FROM
(
SELECT
*
FROM user_interest A
WHERE A.id IN (2,3)
) tOne
INNER JOIN
(
SELECT
*
FROM user_interest A
WHERE A.id IN (2,3)
) tTwo
ON tOne.parent_id = tTwo.parent_id
AND tOne.id <> tTwo.id
ORDER BY tOne.parent_id;
SQL FIDDLE DEMO
Any suggestion towards optimization of the query is welcome.
EDIT: SQL FIDDLE
You can make a sub SELECT:
SELECT * FROM table WHERE Name IN (SELECT Name FROM table GROUP BY Name HAVING count(*) > 1)
I have a problem to split data from attendance machine. The data source after export from it like this:
id name att
1 John 01/04/2015 7:59:00
1 John 01/04/2015 17:44:00
1 John 02/04/2015 7:50:00
1 John 02/04/2015 18:14
Where record (in and out) from fingerprint time save in one column. And I want to split the data to be like this:
id name in out
1 John 01/04/2015 7:59:00 01/04/2015 17:44:00
1 John 02/04/2015 7:50:00 02/04/2015 18:14:00
How to split those record into 2 column in MySQL or PHP (maybe)? Thank you.
Assuming there is only one in/out per day, it's as simple as self-joining on the date and greater time.
select t1.id, t1.name, t1.att as `in`, t2.att as `out`
from table1 t1
inner join table1 t2
on date(t1.att) = date(t2.att) and t1.id = t2.id
and t2.att > t1.att
sql fiddle demo
If you want to create a brand new table with this data, so you can get rid of the import, you just need to use this query as the input to create table, like so:
create table new_table
as
select t1.id, t1.name, t1.att as `in`, t2.att as `out`
from table1 t1
inner join table1 t2
on date(t1.att) = date(t2.att) and t1.id = t2.id
and t2.att > t1.att
You could try this one.
SELECT a.userID,a.name,min(a.att)as `in`,max(a.att) as `out`
FROM
(
SELECT userID,name,str_to_date(att,'%m/%d/%Y%T') as att,str_to_date(att,'%m/%d/%Y') as attd
FROM attendance
) as a
GROUP BY a.userID,a.attd
I'm very new with SQL and need assistance on how I can accomplish this task using the correct query.
I have 2 tables that I need to use. Table "TB1" has:
id Name
1 bob
2 blow
3 joe
table "TB2" has:
compid property
1 bob
2 blow
I am trying to get which compid is missing in "TB2" and insert it from "TB1"
the query I am doing is:
SELECT id, name from TB1, TB2 where id <> compid
what I get is 2 ouputs of Id 1, and 2, and 3 outputs from id 3. by using php:
for($i=0;$i <= mysql_num_rows($comp)-1; $i++)
{
echo mysql_result($comp, $i, 0)."<br>";
}
and I expected the ouput 3 but instead got this:
1
1
2
2
3
3
3
I understand its comparing all the rows within the table but is there a way to achieve what I am looking for?
Thanks for your time.
You are performing an implicit Cartesian JOIN which results in every row against every other row. You need to specify what attribute JOINs the two tables.
Using implicit syntax (not recommended):
SELECT id, name
FROM TB1, TB2
WHERE id <> compid
AND TB1.Name = TB2.property <-- Column join
Using explicit syntax:
SELECT id, name
FROM TB1
JOIN TB2
ON TB2.property = TB1.Name <-- Column join
WHERE id <> compid
To accomplish your goal you would need something along the lines of:
SELECT TB1.id, TB1.name
FROM TB1
LEFT JOIN TB2
ON TB2.property = TB1.Name
WHERE TB2.compid IS NULL
See it in action
It's best practice to always alias the columns you select to prevent ambiguity.
To select it you can do:
SELECT *
FROM TB1
WHERE id NOT IN (
SELECT compid
FROM TB2
);