How to select employee full name, from three different tables - mysql

I have three table person_firstname,person_middlename,person_lastname. All tables have common field entity_id. I have to select employee full name in single record . It is not sure person have only first name, all name or only last name. I tried union it returns three row.
Also need record of specific employee that is by entity_id. SO need to match record like entity_id=123. All names of employee whose entity_id is 123.

SELECT p1.first_name person_firstname,p2.middle_name person_middlename,p3.last_name person_lastname
FROM person_firstname p1 JOIN person_middlename p2 ON p1.entity_id=p2.entity_id
JOIN person_lastname p3 ON p3.entity_id=p2.entity_id;

/*
DROP TABLE PERSON_FIRSTNAME;
DROP TABLE PERSON_SECONDNAME;
DROP TABLE PERSON_LASTNAME;
CREATE TABLE PERSON_FIRSTNAME (ID INT, NAME VARCHAR(20));
CREATE TABLE PERSON_SECONDNAME (ID INT, NAME VARCHAR(20));
CREATE TABLE PERSON_LASTNAME (ID INT, NAME VARCHAR(20));
TRUNCATE TABLE PERSON_FIRSTNAME;
INSERT INTO PERSON_FIRSTNAME VALUES(1,'af'),(2,'bf') ;
TRUNCATE TABLE PERSON_SECONDNAME;
INSERT INTO PERSON_SECONDNAME VALUES(1,'as') ,(3,'cs') ;
TRUNCATE TABLE PERSON_LASTNAME;
INSERT INTO PERSON_LASTNAME VALUES(1,'al'),(2,'bl') ;
*/
SELECT S.*,
PF.NAME,
PS.NAME,
PL.NAME,
concat(IFnull(PF.NAME,''),IFnull(PS.NAME,''),IFNULL(PL.NAME,''))
FROM
(
SELECT ID FROM PERSON_FIRSTNAME
UNION
SELECT ID FROM PERSON_SECONDNAME
UNION
SELECT ID FROM PERSON_LASTNAME
) S
left outer JOIN PERSON_FIRSTNAME PF ON PF.ID = S.ID
left outer JOIN PERSON_SECONDNAME PS ON PS.ID = S.ID
left outer JOIN PERSON_LASTNAME PL ON PL.ID = S.ID

Related

ERROR : Single-row subquery returns more than one row. I am trying to add data in column

I created a temp table and want to insert values in the table using select statements but when I run this query I am getting the above error. Is there any efficient way.
DROP TABLE IF EXISTS MANAGER_DATA;
CREATE TEMPORARY TABLE MANAGER_DATA (
WORKER_ID VARCHAR, ACCOUNT VARCHAR,
ACTIVE Boolean, REPORTING_NAME VARCHAR,
BUSINESS_TITLE VARCHAR, MANAGER_WORKER_ID VARCHAR,
MANAGER_REPORTING_NAME Text, MANAGER_OF_MANAGER_ID VARCHAR,
MANAGER_OF_MANAGER_NAME VARCHAR);
INSERT INTO MANAGER_DATA (
SELECT WORKER_ID,
ACCOUNT,
ACTIVE,
REPORTING_NAME,
BUSINESS_TITLE,
MANAGER_WORKER_ID,
(
SELECT
A.REPORTING_NAME
FROM ALL_ASSOCIATES_V AS A
INNER JOIN ALL_ASSOCIATES_V AS B
ON A.MANAGER_WORKER_ID = B.WORKER_ID),
(
SELECT B.MANAGER_WORKER_ID
FROM ALL_ASSOCIATES_V AS A
INNER JOIN ALL_ASSOCIATES_V AS B
ON A.MANAGER_WORKER_ID = B.WORKER_ID),
NULL
FROM ALL_ASSOCIATES_V
);
SELECT * FROM MANAGER_DATA;

MySQL: Use a single Column to show as multiple select column in single row

Consider these example tables
E_id in Table1 is a primary key. From and Assign_to are foreign keys referenced with E_id.
I want to show a table like this:
I am not sure how I can implement it. Please share the SQL query which returns the desired table.
You could JOIN to Table1 twice:
SELECT
t2.work_name,
t1f.E_name AS `From`,
t1a.E_Name AS `Assign_to`
FROM Table2 t2
INNER JOIN Table1 t1f
ON t1f.E_id = t2.`from`
INNER JOIN Table1 t1a
ON t1a.E_id =t2.Assign_to
You can solve that problem with a simple temp table. It is not the most sophisticated way to solve it, but the solution is easy to comprehend.
The step are as followed:
Create a table with all data from table2
Add 2 columns to that table to store the name values for from and Assign_to
Update the columns with the name values from table1
Select your Data
MySQL-Code
-- create temp-table
CREATE TABLE table2_temp
SELECT * FROM table2;
-- add columns to enrich table with E_name from table1
ALTER TABLE table2_temp
ADD COLUMN E_name_from VARCHAR (125),
ADD COLUMN E_name_assign_to VARCHAR (125);
-- update temp-table with names from table1
-- for E_name_from
UPDATE table2_temp A
INNER JOIN table1 B ON (A.`from` = E_id)
SET A.E_name_from = B.E_name;
-- for E_name_assign_to
UPDATE table2_temp A
INNER JOIN table1.B ON (A.Assign_to = E_id)
SET A.E_name_assign_to = B.E_name;
-- now you can select your date from the temp-table
SELECT
work_name,
E_name_from AS `From`,
E_name_assign_to AS `Assign_to`
FROM
table2_temp;
-- drop table after work is done
drop table if exists table2_temp ;

Deleting duplicates with a where clause

Hey so I have one set of data with the structure:
id product_number product_type
1 1001 car
2 1002 house
But the data has some duplicates where:
id product_number product_type
1 1001 car
2 1001 house
I need to delete the duplicates but only the value which is = house.
In my mind the query should be like:
DELETE *
FROM table
WHERE product_number is duplicate AND product_type = house
Thanks
In MySQL, you can do what you want with a join:
delete t
from table t join
(select product, count(*) as cnt
from table
group by product
) tt
on tt.product = t.product
where tt.cnt > 1 and t.product_type = 'house';
You have multiple methods:
1.
You can use this query:
INSERT INTO new_table (SELECT DISTINCT * FROM old_table WHERE product_type = house)
2.
You can alter your table and change your product number column to add an index to it
ALTER IGNORE TABLE jobs
ADD UNIQUE INDEX idx_name (product_number);
So the duplicated row with the same product number will be dropped automatically, and for more see this link here
3.
You can try this query to:
DELETE n1 FROM table_product p1, table_product p2 WHERE p1.product_number = p2.product_number AND p1.product_type= house
You can use an UPDATE query with a join like this:
delete t1.*
from
t t1 INNER JOIN t t2
ON t1.product_number = t2.product_number
AND t1.product_type='house' AND (
t2.product_type<>'house'
OR t1.id>t2.id
)
DELETE *
FROM table
WHERE id not in
(select max(id) from table
group by product_number)
AND product_type = house

WITH clause in MySQL?

Does MySQL support common table expressions? For example in Oracle there's the WITH clause? :
WITH aliasname
AS
( SELECT COUNT(*) FROM table_name )
SELECT COUNT(*) FROM dept,aliasname
SELECT t.name,
t.num
FROM TABLE t
JOIN (SELECT c.id,COUNT(*) 'num1'
FROM TABLE1 c
WHERE c.column = 'a'
GROUP BY c.id) ta1 ON ta1.id = t.id
JOIN (SELECT d.id,COUNT(*) 'num2'
FROM TABLE2 d
WHERE d.column = 'a'
GROUP BY d.id) ta2 ON ta2.id = t.id
One way is to use a subquery:
SELECT COUNT(*)
FROM dept,
(
SELECT COUNT(*)
FROM table_name
) AS aliasname
Note that the , between the two tables will cross join the two tables the same as in your query you posted. IF there is any relation between them you can JOIN them instead.
No, MySQL does not support Common Table Expressions (CTE). So instead of using WITH tablealias as (....), you will have to do a subquery.
For example,
WITH totalcount AS
(select userid, count(*) as tot from logins group by userid)
SELECT a.firstname, a.lastname, b.tot
FROM users a
INNER JOIN
totalcount b
on a.userid = b.userid
can be re-written in MySQL as
SELECT a.firstname, a.lastname, b.totalcount
FROM users a
INNER JOIN
(select userid, count(*) as tot from logins group by userid) b
on a.userid = b.userid
So let's talk about WITH clause .
WITH clause and INNER JOIN otherwise JOIN are a kind of same , but WITH clause gives you much more latitude especially in WHERE clause ;
I am going to make a view that'll get values like count of users , user name and etc.
First (Creating our tables users and inserted_users) :
inserted_users table :
CREATE TABLE users (id BIGINT(10) AUTO INCEREMENT PRIMARY KEY , name VARCHAR(50))
users table :
CREATE TABLE users (id BIGINT(10) AUTO INCEREMENT PRIMARY KEY , name VARCHAR(50) , gender TINYINT(1))
Second (Inserting some values to work with) :
users table :
INSERT INTO users (name,gender) VALUES ('Abolfazl M' , 1)
I don't want to insert into inserted_users by query , but I want to add a TRUGGER which will insert data automatically to users_inserted table before data be inserted into users table.
Third (Creating trigger add_uinserted) :
DELIMITER $$
CREATE TRIGGER IF NOT EXISTS add_uinserted BEFORE INSERT ON users FOR EACH ROW
BEGIN
IF NEW.name <> '' THEN
INSERT INTO users_inserted (name) VALUES (NEW.name);
ELSE
INSERT INTO users (name,gender) VALUES ('Unknown',NEW.gender);
INSERT INTO users_inserted (name) VALUES ('Unknown');
END IF;
END$$
DELIMITER ;
Run the query and the trigger will be created and at last let's create a view to give us result from a query having WITH clause .
CREATE VIEW select_users AS
WITH GetCAll AS (
SELECT u1.id As Uid ,COUNT(u1.name) AS CnAll FROM users u1
)
SELECT u1.name AS NAME,CASE
WHEN s1.gender = 1 THEN "MALE"
WHEN s1.gender = 0 THEN "FEMALE"
ELSE "UNKNOWN"
END AS GENDER,CASE
WHEN u1.id = gca.Uid THEN "INSERTED TO users_inserted"
ELSE "NOT INSERTED TO users_inserted"
END AS INSERTED,gca.CnAll FROM GetCAll AS gca INNER JOIN users u1;
After you query got ran the view will be created and by calling the view select_users the data will be shown
Last step (calling the select_users view) :
SELECT * FROM select_users
Thanks for taking a look at my answer , and that's it !!

how do I fix this DELETE query?

I have two tables: products(product_id,date) and sex(product_id,sex).
I want to DELETE from the products table all products having a product_id for which a row exists in the sex table with this product_id and sex=1.
I also wish to DELETE from the sex table all rows containing a product_id contained in one of the rows I am deleting from the products table. (This may delete multiple rows per product_id.)
So far I have
DECLARE #recordsToDelete AS TABLE(
int product_id
);
INSERT INTO #recordsToDelete( product_id )
SELECT product_id
FROM products p
JOIN sex s
ON p.product_id = s.product_id
WHERE s.sex = 1;
I will then test with
SELECT * FROM #recordsToDelete;
before executing
DELETE FROM products
WHERE product_id IN ( SELECT product_id FROM #recordsToDelete );
DELETE FROM sex
WHERE product_id IN ( SELECT product_id FROM #recordsToDelete );
but the DECLARE statement is giving me a syntax error. I note here that DECLARE requires a BEGIN/END compound statement, but I am unable to formulate it properly. How can I correct my mistake?
EDIT:
fixed via
CREATE TEMPORARY TABLE recordsToDelete(
product_id INT
);# MySQL returned an empty result set (i.e. zero rows).
INSERT INTO recordsToDelete( product_id )
SELECT p.product_id
FROM products p
JOIN sex s ON p.product_id = s.product_id
WHERE s.sex =1;# Affected rows: 275
SELECT *
FROM recordsToDelete;
I think you're looking for CREATE TEMPORARY TABLE to create your table instead of DECLARE.
See this page for more info on creating tables in MySQL.
The syntax you're using is appears to be for MS SQL server, not MySQL. In MySQL, DECLARE is used for local variables, conditions, handlers, and cursors, but not for creating tables.
Try this instead?
CREATE TEMPORARY TABLE tempTable
SELECT product_id
FROM products AS p
INNER JOIN sex AS s
ON p.product_id = s.product_id
WHERE s.sex = 1;
DELETE FROM products AS p
NATURAL JOIN tempTable AS t
WHERE p.product_id = t.product_id;
Btw, you can't DELETE FROM same_table (SELECT * FROM same_table).
I quote:
Currently, you cannot delete from a table and select from the same table in a subquery.
http://dev.mysql.com/doc/refman/5.5/en/delete.html
I think you can get what you want from a simple multitable delete:
delete sex, products from products p
inner join sex s on p.id=s.product_id
where s.sex=1
You can also consider using on cascade delete on your table:
http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html