MySQL get linked results from the same table - mysql

I can't wrap my head around a small (hopefully) MySQL question. I have a table called links. It contains a customer_id field and a linked_id field and basically links customer accounts to each other where customer_id is in the lead. The newly created accounts can spawn accounts themselves and I would like to see all accounts that were created by the logged on user + all the accounts created by subaccounts.
Table looks like this:
+----+-------------+-----------+
| id | customer_id | linked_id |
+----+-------------+-----------+
| 1 | 1 | 5 |
| 2 | 1 | 2 |
| 3 | 1 | 11 |
| 4 | 1 | 13 |
| 5 | 13 | 14 |
| 6 | 3 | 4 |
| 7 | 7 | 8 |
+----+-------------+-----------+
So if I am logged in as user with customer_id 1 then I would like to get the userlist with linked_id 5,2,11,13 (because they are a direct connection) and linked_id 14 (because this user was created by a user who is directly connected to 1).
The query needs to be a subquery to get all user details. I currently have:
SELECT username, firstname, lastname, email, active, level FROM customers WHERE id
IN (SELECT linked_id FROM links WHERE customer_id=1) or id=1;
This obviously only returns the direct connections and the user with id=1 directly.

Thanks to eggyal for putting me on the right track. Seeing the relative complexity I do not feel so ashamed anymore that I could not crack it in the first go.
I ended up doing some research and found some nice setups to used closure tables in mysql. I ended up creating a stored procedure to populate my closure table and of course the new table cust_closure. I renamed by links table to cust_links.
cust_links:
+-------------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| customer_id | int(11) | YES | | NULL | |
| linked_id | int(11) | YES | | NULL | |
+-------------+---------+------+-----+---------+----------------+
cust_closure:
+-------------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+---------+------+-----+---------+-------+
| customer_id | int(11) | YES | | NULL | |
| linked_id | int(11) | YES | | NULL | |
| distance | int(11) | YES | | NULL | |
+-------------+---------+------+-----+---------+-------+
And then added the stored procedure:
CREATE PROCEDURE populate_cust_closure()
BEGIN
DECLARE distance int;
TRUNCATE TABLE cust_closure;
SET distance = 0;
-- seed closure with self-pairs (distance 0)
INSERT INTO cust_closure (customer_id, linked_id, distance)
SELECT customer_id, customer_id, distance
FROM cust_links GROUP BY customer_id;
-- for each pair (root, leaf) in the closure,
-- add (root, leaf->child) from the base table
REPEAT
SET distance = distance + 1;
INSERT INTO cust_closure (customer_id, linked_id, distance)
SELECT cust_closure.customer_id, cust_links.linked_id, distance
FROM cust_closure, cust_links
WHERE cust_closure.linked_id = cust_links.customer_id
AND cust_closure.distance = distance - 1;
UNTIL ROW_COUNT()=0
END REPEAT;
END //
When I then called the stored procedure it produced:
mysql> select * from cust_closure;
+-------------+-----------+----------+
| customer_id | linked_id | distance |
+-------------+-----------+----------+
| 1 | 1 | 0 |
| 3 | 3 | 0 |
| 7 | 7 | 0 |
| 13 | 13 | 0 |
| 1 | 5 | 0 |
| 1 | 2 | 0 |
| 1 | 11 | 0 |
| 1 | 13 | 0 |
| 13 | 14 | 0 |
| 1 | 14 | 1 |
| 3 | 4 | 0 |
| 7 | 8 | 0 |
+-------------+-----------+----------+
So now my original query becomes:
SELECT username, firstname, lastname, email, active, level FROM customers WHERE id
IN (SELECT linked_id FROM cust_closure WHERE customer_id=1);
Thanks again for eggyal and hope this helps someone in the future.

Related

SQL Query returns incorrect count [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I am trying to get the count of all the feature and the feature name against an application by using MySQL query. Here is the query:
select t2.feature,count(t2.feature) as count from judge_task t1, approve t2 where t1.application_name='Retail Bank Portal' AND t2.gap_status=1 group by feature;
Here is the description of my tables:
Table judge_task
+------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+--------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| application_id | int | NO | | NULL | |
| application_name | varchar(50) | YES | | NULL | |
| feature_id | int | NO | | NULL | |
| feature_name | varchar(50) | YES | | NULL | |
| task_type | int | NO | | NULL | |
Table approve
+------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+--------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| feature | varchar(500) | NO | | 0 | |
| gap_status | int | NO | | 3 | |
+------------------+--------------+------+-----+---------+----------------+
There is no relationship like foreign key between both the tables. The database was designed by someone else and it can not be updated now as the application is almost completed. Updating the database will disturb the whole application design.
Here is the result of the query:
+---------+-----+
| feature | app |
+---------+-----+
| S3 | 175 |
| Login | 875 |
+---------+-----+
The original count are as follows:
S3 = 1,
Login = 5
I am not getting the exact query to get my results. Would you please suggest me a correction to my query? How should I update it to get my results? Thanks a lot
Update 1
sample data for judge_task is here
| 100173 | 4 | Retail Bank Portal | 16 | Login | 1 |
| 100203 | -1 | Retail Bank Portal | 16 | Login | 2 |
| 100204 | 4 | Retail Bank Portal | 19 | Bill Pay | 2 |
| 100205 | -1 | Retail Bank Portal | 16 | Login | 2 |
| 100206 | -1 | Retail Bank Portal | 16 | Login | 2 |
| 100207 | -1 | Retail Bank Portal | 16 | Login | 2 |
| 100208 | -1 | Retail Bank Portal | 16 | Login | 2 |
| 100209 | -1 | Retail Bank Portal | 22 | S3 | 2 |
Sample data for approve
| 59 | Login | 1 |
| 60 | Login | 1 |
| 115 | Login | 1 |
| 116 | Login | 1 |
| 117 | Login | 3 |
| 118 | Login | 3 |
| 119 | Login | 3 |
| 120 | Login | 3 |
| 121 | Login | 3 |
| 122 | Login | 3 |
| 123 | Login | 3 |
| 124 | Login | 3 |
| 125 | Login | 3 |
| 126 | Login | 3 |
| 127 | Login | 3 |
| 128 | Login | 1 |
| 129 | S3 | 1 |
+-----+-------------------------+------------+
I have updated the table definitions according to sample data removing the irrelevant columns. Thanks
Update
One thing I forget to mention that the data has to be selected from approve table and just the application name is to be selected from judge_task.
Here is how I'd make the query:
SELECT DISTINCT
t.feature, t.feature_count
FROM judge_task
INNER JOIN (
SELECT
app.feature, COUNT(*) AS feature_count
FROM approve app
WHERE app.gap_status = 1
GROUP BY app.feature
) AS t ON t.feature = judge_task.feature_name
WHERE judge_task.application_name = 'Retail Bank Portal'
;
You can see the result in this SQLFiddle
With the inner select you can avoid duplication of result due to the Cartesian product with the approve table
You are performing a(n implicit) CROSS JOIN with your query, which means, all rows from table A are combined with table B in the background.
First find the way you can explicitly join your tables (feature_id = feature.id maybe?)
Use explicit join (INNER JOIN, LEFT JOIN, RIGHT JOIN, etc) instead of implicit one (listing the tables with comas in the FROM clause).
First: you do not need a foreign key to join two tables in a query. All you need is a field in both tables with the "same data", that allows to acreate this relation, for example, a "TaskID" or anything like this (the name of the field is not nesessary the same).
The only fields in your tables that allow to create this connection in your tables are: judge_task.feature_name and approve.feature. I guess we can try this query:
select t2.feature, count(t2.id) from judge_task as t1
join approve as t2 on t2.feature = t1.feature_name
where t1.application_name='Retail Bank Portal' AND t2.gap_status=1
group by feature;
If your tables have many rows I recommend that you create indexes on judge_task.feature_name and approve.feature (as well as on judge_task.application_name) to improve performance.

mysql pivot using column and row numbers

I am stuck in this situation where I need to use Row Number and Column Number values from table's columns to derive the output mentioned below. I have tried everything - if/else, case when/then but not helping.
Any help/suggestions are really appreciated!
Here is a mocked up sample data present in db table -
+--------+--------+--------+----------+-------------+
| Record | ColNbr | RowNbr | ColTitle | CellContent |
+--------+--------+--------+----------+-------------+
| 1 | 1 | 1 | Unit | sqf |
| 1 | 1 | 2 | Unit | cm |
| 1 | 2 | 1 | Desc | roof |
| 1 | 2 | 2 | Desc | rod |
| 1 | 3 | 1 | Material | concrete |
| 1 | 3 | 2 | Material | steel |
| 1 | 4 | 1 | Quantity | 100 |
| 1 | 4 | 2 | Quantity | 12 |
| 1 | 1 | 1 | Unit | liter |
| 1 | 1 | 2 | Unit | ml |
| 1 | 2 | 1 | Desc | bowl |
| 1 | 2 | 2 | Desc | plate |
| 1 | 3 | 1 | Material | plastic |
| 1 | 3 | 2 | Material | glass |
| 1 | 4 | 1 | Quantity | 2 |
| 1 | 4 | 2 | Quantity | 250 |
+--------+--------+--------+----------+-------------+
Expected Output -
+--------+--------+--------+----------+-------------+
| Record | Unit | Desc | Material | Quantity |
+--------+--------+--------+----------+-------------+
| 1 | sqf | roof | concrete | 100 |
| 1 | cm | rod | steel | 12 |
| 2 | liter | bowl | plastic | 2 |
| 2 | ml | plate | glass | 250 |
+--------+--------+--------+----------+-------------+
If your actual data is like that, I suggest that you consider to separate the data to; for example, 4 different tables (unit,description,material & a table to store all that ids+quantity). The former 3 tables will store the prerequisite info that get minor updates throughout time and the last table will store all the quantity records. Let's say your tables will look something like this:
CREATE TABLE `Unit` (
unit_id INT,
unit_name VARCHAR(50));
+---------+-----------+
| unit_id | unit_name |
+---------+-----------+
| 1 | sqf |
| 2 | cm |
| 3 | liter |
| 4 | ml |
+---------+-----------+
CREATE TABLE `Description` (
desc_id INT,
desc_name VARCHAR(50));
+---------+-----------+
| desc_id | desc_name |
+---------+-----------+
| 1 | roof |
| 2 | rod |
| 3 | bowl |
| 4 | plate |
+---------+-----------+
CREATE TABLE `Material` (
mat_id INT,
mat_name VARCHAR(50));
+--------+----------+
| mat_id | mat_name |
+--------+----------+
| 1 | concrete |
| 2 | steel |
| 3 | plastic |
| 4 | glass |
+--------+----------+
CREATE TABLE `Records` (
unit_id INT,
desc_id INT,
mat_id INT,
quantity DECIMAL(14,4));
+---------+---------+--------+----------+
| unit_id | desc_id | mat_id | Quantity |
+---------+---------+--------+----------+
| 1 | 1 | 1 | 100 |
| 2 | 2 | 2 | 12 |
| 3 | 3 | 3 | 2 |
| 4 | 4 | 4 | 250 |
+---------+---------+--------+----------+
Then you insert the data accordingly.
Anyhow, for your existing data example, it could be done but there are some concern over whether the unit+desc+material+quantity matching are correct. The only way I can maybe at least think that it's correctly matched is by giving all of the query a similar ORDER BY clause. Hence, the following:
SELECT A.record,A.unit,B.Desc,C.Material,D.Quantity FROM
(SELECT #rn:=#rn+1 AS record,CASE WHEN coltitle='unit' THEN cellcontent END AS Unit
FROM yourtable, (SELECT #rn :=0 ) v
HAVING unit IS NOT NULL
ORDER BY colnbr) A LEFT JOIN
(SELECT #rn1:=#rn1+1 AS record,CASE WHEN coltitle='Desc' THEN cellcontent END AS `Desc`
FROM yourtable, (SELECT #rn1 :=0 ) v
HAVING `Desc` IS NOT NULL
ORDER BY colnbr) B ON a.record=b.record LEFT JOIN
(SELECT #rn2:=#rn2+1 AS record,CASE WHEN coltitle='material' THEN cellcontent END AS Material
FROM yourtable, (SELECT #rn2:=0 ) v
HAVING Material IS NOT NULL
ORDER BY colnbr) C ON a.record=c.record LEFT JOIN
(SELECT #rn3:=#rn3+1 AS record,CASE WHEN coltitle='Quantity' THEN cellcontent END AS Quantity
FROM yourtable, (SELECT #rn3:=0 ) v
HAVING Quantity IS NOT NULL
ORDER BY colnbr) D ON a.record=d.record;
The idea here is to make a sub-query based on COLTITLE then assign a numbering/ranking (#rn,#rn1,#rn2,#rn3) variable to each of the sub-query and join them up using LEFT JOIN. Now, this experiment works to exactly return the output that you need but its not a definite answer because there are some part that is questionable especially on matching the combination correctly. Hopefully, this will give you some idea.

Counting multiple value ocurrences on multiple columns in a single query

I have a search section for looking up products which has a navigation bar for filtering purposes that shows the total results of each product feature. For example:
TOTAL RESULTS 60
New (32)
Used (28)
Particular (10)
Company (50)
In mysql I have the following queries (one per feature)
Type
SELECT a.id_type, whois.name as whoisName, COUNT(a.id_type) as countWhois
FROM (published a
INNER JOIN types whois ON whois.id = a.id_type)
GROUP BY id_type
+---------+------------+------------+
| id_type | whoisName | countWhois |
+---------+------------+------------+
| 0 | Company | 50 |
| 1 | Particular | 10 |
+---------+------------+------------+
Condition
SELECT a.id_condition, cond.name as condName, COUNT(a.id_condition) as countCondition
FROM (published a
INNER JOIN conditions cond ON cond.id = a.id_condition)
GROUP BY id_condition
+--------------+---------------+----------------+
| id_condition | conditionName | countCondition |
+--------------+---------------+----------------+
| 0 | New | 32 |
| 1 | Used | 28 |
+--------------+---------------+----------------+
I want to summarize the two queries in a single one but canĀ“t figure out how. I was thinking something like this:
+---------+------------+------------+--------------+---------------+----------------+
| id_type | whoisName | countWhois | id_condition | conditionName | countCondition |
+---------+------------+------------+--------------+---------------+----------------+
| 0 | Company | 50 | NULL | NULL | NULL |
| 1 | Particular | 10 | NULL | NULL | NULL |
| NULL | NULL | NULL | 0 | New | 32 |
| NULL | NULL | NULL | 1 | Used | 28 |
+---------+------------+------------+--------------+---------------+----------------+
Is this possible?
Thanks and sorry if my English is bad, it's not my native language.

How to query for all information of an entity within an Entity-Attribute-Value (EAV) model?

I've searched about this and tried to make it myself over the last few days but I just couldn't. The closest I've gotten within my search was this answer, also on Stack Overflow: EAV Select query from spreaded value tables
So here I am, turning myself to the Internet!
So, I have a database which makes use of the EAV (Entity-Attribute-Value) model. But here's the catch: the actual entities aren't directly connected to the other EAV tables. Let me be more specific; say that there is a Person and a Site tables, and that they only have their primary keys: person_id and site_id, respectively.
Because the attributes (called "properties" on my schema) of those entities (i.e. the Person and the Site) must be dynamic, they must all be stored outside their respective tables, i.e. the EAV tables. The following is the EAV part of the database schema (I'm not sure if it's completely correct, so please let me know if you have any suggestion). -- http://i.stack.imgur.com/EN3dy.png
The EAV part of the schema basically has the following tables:
property
property_value_varchar
property_value_text
property_value_number
property_value_boolean
property_value_datetime
entity_tables
Ok, so, since the Entities aren't "directly connected" to the EAV part, I'm using the entity_tables table just as a reference to the actual tables, so, with the example above, the entity_tables table should look something like this:
---------------------------------------
|entity_table_id | entity_table_name |
| 1 | person |
| 2 | site |
| . | . |
| . | . |
---------------------------------------
The property table is the one that actually holds the different properties that any entity can hold, say "PERSON_FIRST_NAME" or "LOCATION_NAME", or anything else.
The property_value_* tables are all exactly the same except on the datatype of the property_value. These are the ones that hold the actual value of each Entity's object's property, which get mapped by the entity_table_id and entity_object_id.
Let me give you a possible instance of the database, for clarity:
Person table
-------------
| person_id |
| 1 |
| 2 |
-------------
Site table
-----------
| site_id |
| 1 |
| 2 |
-----------
entity_tables table
---------------------------------------
|entity_table_id | entity_table_name |
| 1 | person |
| 2 | site |
---------------------------------------
property table
-------------------------------------
| property_id | property_code |
| 1 | PERSON_FIRST_NAME |
| 2 | PERSON_LAST_NAME |
| 3 | PERSON_BIRTH_DATE |
| 4 | SITE_NAME |
| 5 | SITE_PHONE_NR_1 |
| 6 | SITE_PHONE_NR_2 |
| 7 | SITE_LATITUDE |
| 8 | SITE_LONGITUDE |
| 9 | SITE_CITY |
| 10 | SITE_COUNTRY |
| 11 | SITE_ZIP_CODE |
-------------------------------------
property_value_varchar table
-----------------------------------------------------------------------------------------
| property_value_id | property_id | entity_table_id | entity_object_id | property_value |
| 1 | 1 | 1 | 1 | Richard |
| 2 | 2 | 1 | 1 | Hammer |
| 3 | 1 | 1 | 2 | Bruce |
| 4 | 2 | 1 | 2 | Heaton |
| 5 | 4 | 2 | 1 | BatCave |
| 6 | 5 | 2 | 1 | +49123456789 |
| 7 | 4 | 2 | 2 | BigCompany |
| 8 | 5 | 2 | 2 | 987654321 |
| 9 | 6 | 2 | 2 | 147852369 |
| 10 | 9 | 2 | 2 | Berlin |
| 11 | 10 | 2 | 2 | Germany |
| 12 | 11 | 2 | 2 | 14167 |
-----------------------------------------------------------------------------------------
property_value_datetime table
-----------------------------------------------------------------------------------------
| property_value_id | property_id | entity_table_id | entity_object_id | property_value |
| 1 | 3 | 1 | 1 | 1985-05-31 |
-----------------------------------------------------------------------------------------
property_value_number table
-----------------------------------------------------------------------------------------
| property_value_id | property_id | entity_table_id | entity_object_id | property_value |
| 1 | 7 | 2 | 1 | 1.402636 |
| 2 | 8 | 2 | 1 | 7.273922 |
-----------------------------------------------------------------------------------------
(property_value_text and property_value_boolean tables are empty)
As you could see, not all objects of each entity have necessarily the same properties (attributes). The domain is really loose like that.
So, now like so many people before me, I'm not sure how to retrieve all of this information in a readable way, namely how can I get all of the information concerning the records of the Person table or of the Site table?
Namely, how can I get something like this:
Person table view
----------------------------------------------------
| Person ID | Property code | Property value |
| 1 | PERSON_FIRST_NAME | Richard |
| 1 | PERSON_LAST_NAME | Hammer |
| 1 | PERSON_BIRTH_DATE | 1985-05-31 |
| 2 | PERSON_FIRST_NAME | Bruce |
| 2 | PERSON_LAST_NAME | Heaton |
----------------------------------------------------
Site table view
------------------------------------------------
| Site ID | Property code | Property value |
| 1 | SITE_NAME | Batcave |
| 1 | SITE_PHONE_NR_1 | +49123456789 |
| 1 | SITE_LATITUDE | 1.402636 |
| 1 | SITE_LONGITUDE | 7.273922 |
| 2 | SITE_NAME | BigCompany |
| 2 | SITE_PHONE_NR_1 | 987654321 |
| 2 | SITE_PHONE_NR_2 | 147852369 |
| 2 | SITE_CITY | Berlin |
| 2 | SITE_COUNTRY | Germany |
| 2 | SITE_ZIP_CODE | 14167 |
------------------------------------------------
Or even like this, if it is easier:
Person table view
------------------------------------------------------------------------
| Person ID | PERSON_FIRST_NAME | PERSON_LAST_NAME | PERSON_BIRTH_DATE |
| 1 | Richard | Hammer | 1985-05-31 |
| 2 | Bruce | Heaton | |
------------------------------------------------------------------------
Site table view
----------------------------------------------------------------------------------------------------------------------------------------
| Site ID | SITE_NAME | SITE_PHONE_NR_1 | SITE_PHONE_NR_2 | SITE_LATITUDE | SITE_LONGITUDE | SITE_CITY | SITE_COUNTRY | SITE_ZIP_CODE |
| 1 | Batcave | +49123456789 | | 1.402636 | 7.273922 | | | |
| 2 | BigCompany | 987654321 | 147852369 | | | Berlin | Germany | 14167 |
----------------------------------------------------------------------------------------------------------------------------------------
I realize this can be quite confusing. Please let me know how else I can help you help me, like more information or better explaining of some part.
I also don't expect 1 SQL query (per entity) to do the trick. I realize that more than 1 query is likely and that it/they would very likely need to be "assembled" by PHP (for instance), in order to really make it dynamic. So even if someone could even just explain me how I could get all of this info just for the hypothetical properties (attribute) that I have above, I would already be immensely grateful!
Thank you for any help!
This was a fun question! This can be handled with dynamic sql. In the code below, the schema has been recreated with temp tables. The code could be turned into a stored procedure that takes an entity_table_id as a parameter and then selects the entity_object_id as entity_table_name + 'id' followed by every property_value as columns with the corresponding property_code as the headings.
-- load EAV tables
if object_id('tempdb..#entity_tables') is not null
drop table #entity_tables
create table #entity_tables(entity_table_id int,entity_table_name varchar(255))
insert into #entity_tables values
(1,'person'),
(2,'site')
if object_id('tempdb..#property') is not null
drop table #property
create table #property(property_id int,property_code varchar(255))
insert into #property values
(1,'PERSON_FIRST_NAME'),
(2,'PERSON_LAST_NAME'),
(3,'PERSON_BIRTH_DATE'),
(4,'SITE_NAME'),
(5,'SITE_PHONE_NR_1'),
(6,'SITE_PHONE_NR_2'),
(7,'SITE_LATITUDE'),
(8,'SITE_LONGITUDE'),
(9,'SITE_CITY'),
(10,'SITE_COUNTRY'),
(11,'SITE_ZIP_CODE')
if object_id('tempdb..#property_value_varchar') is not null
drop table #property_value_varchar
create table #property_value_varchar(property_value_id int,property_id int,entity_table_id int,entity_object_id int,property_value varchar(255))
insert into #property_value_varchar values
(1,1,1,1,'Richard'),
(2,2,1,1,'Hammer'),
(3,1,1,2,'Bruce'),
(4,2,1,2,'Heaton'),
(5,4,2,1,'BatCave'),
(6,5,2,1,'+49123456789'),
(7,4,2,2,'BigCompany'),
(8,5,2,2,'987654321'),
(9,6,2,2,'147852369'),
(10,9,2,2,'Berlin'),
(11,10,2,2,'Germany'),
(12,11,2,2,'14167')
if object_id('tempdb..#property_value_datetime') is not null
drop table #property_value_datetime
create table #property_value_datetime(property_value_id int,property_id int,entity_table_id int,entity_object_id int,property_value datetime)
insert into #property_value_datetime values
(1,3,1,1,'1985-05-31')
if object_id('tempdb..#property_value_number') is not null
drop table #property_value_number
create table #property_value_number(property_value_id int,property_id int,entity_table_id int,entity_object_id int,property_value float)
insert into #property_value_number values
(1,7,2,1,1.402636),
(2,8,2,1,7.273922)
-- create dynamic sql to get all data conditioned on #entity_tables.table_id value
declare #tableid int,#sql varchar(max)
set #tableid = 1 -- this could be passed as a parameter
-- get pivot code with #ColumnList# placeholders to be added below
select #sql = 'select entity_object_id ' + entity_table_name + 'id,
#ColumnListCast#
from (
select
e.entity_table_name,
pv.entity_object_id,
pv.property_value,
p.property_code
from #entity_tables e
inner join (
select entity_table_id,entity_object_id,property_id,property_value from #property_value_varchar union all
select entity_table_id,entity_object_id,property_id,cast(property_value as varchar(255)) from #property_value_datetime union all
select entity_table_id,entity_object_id,property_id,cast(property_value as varchar(255)) from #property_value_number
) pv
on pv.entity_table_id = e.entity_table_id
inner join #property p
on p.property_id = pv.property_id
where e.entity_table_id = ' + cast(#tableid as varchar(5)) + '
) p
pivot (
max(property_value)
for property_code in (
#ColumnList#
)
) piv' from #entity_tables where entity_table_id = #tableid
-- get column list with cast version for diffferent data types
declare #ColumnList varchar(max),
#ColumnListCast nvarchar(max)
set #ColumnList = ''
set #ColumnListCast = ''
select #ColumnList = #ColumnList + '[' + p.property_code + ']' + case row_number() over(order by p.property_id desc) when 1 then '' else ',' end,
#ColumnListCast = #ColumnListCast + 'cast([' + p.property_code + '] as ' + t.CastValue + ') [' + p.property_code + ']' + case row_number() over(order by p.property_id desc) when 1 then '' else ',' end
from #property p
inner join (
select property_id,'varchar(255)' CastValue from #property_value_varchar where entity_table_id = #tableid union
select property_id,'datetime' CastValue from #property_value_datetime where entity_table_id = #tableid union
select property_id,'float' CastValue from #property_value_number where entity_table_id = #tableid
) t
on t.property_id = p.property_id
order by p.property_id
set #sql = replace(replace(#sql,'#ColumnList#',#ColumnList),'#ColumnListCast#',#ColumnListCast)
exec(#sql)

SQL Insert by from another table through a reference table

I've got three tables in MySQL: wp_usermeta, directory_department, and directory_departmentmemebership
Directory_departmentmembership
| employee_id|department_id|
|:-----------|------------:|
| 1 | 2 |
| 2 | 1 |
| 3 | 3 |
directory_department
| department_id|department_name|
|:----------- |--------------:|
| 1 | Deans |
| 2 | MBA |
| 3 | Fiance |
wp_usermeta has:
| employee_id| meta_key | meta_value |
|:-----------|--------------:|:------------:|
| 1 |department_id | 2 |
| 2 |department_id | 1 |
| 3 |department_id | 3 |
| 1 |department_name| |
| 2 |department_name| |
| 3 |department_name| |
How I can I reference directory_department to insert the correct department_name based off of the department_id value in the meta_value field?
You can use a SQL function to get the right name for each id...
CREATE FUNCTION [dbo].[fn_department](#id INT)
RETURNS VARCHAR(300)
AS
BEGIN
declare #department_name varchar(300)
select #department_name = department_name from directory_department where department_id = #id
RETURN #department_name
END
--And call it like this...
INSERT INTO wp_usermeta (id,department_name)
select id, dbo.fn_department(id) as department_name