I have two tables one for properties and one for users. and I wanna generate a new table that contains propertyID with user name, So i want to loop through the users ids from the properties table then do a query to get the name and assign it to the propertyID like the final table.
Properties
| propertyID | userID |
|------------|--------|
| 123 | 2 |
| 453 | 4 |
| 345 | 6 |
| 378 | 6 |
Users
| userID | name |
|--------|-------|
| 2 | zeyad |
| 4 | test |
| 6 | elan |
Desired Table
| propertyID | name |
|------------|-------|
| 123 | zeyad |
How can i do this?
just like this
CREATE TABLE desiredTable AS
SELECT p.propertyID, u.name FROM Properties p
LEFT JOIN Users u
ON u.userID = p.userID
Careful to the column name you use ("name" is a SQL keyword, use username instead :))
Related
I have a database I extracted from an application (I did not create it). I need to extract the data to use in a different application. The main table contains 3 foreign keys each linking to other tables. I want to replace the FK IDs with a specific column value from those other tables. The main table looks like this:
data:
+------------+------------+--------+----------+-----------+----------+------+
| startdate | enddate | status | employee | cause | duration | type |
+------------+------------+--------+----------+-----------+----------+------+
| 2018-01-05 | 2018-01-07 | 2 | 1 | some text | 3 | 1 |
+------------+------------+--------+----------+-----------+----------+------+
| 2018-02-03 | 2018-02-04 | 1 | 2 | some text | 2 | 2 |
+------------+------------+--------+----------+-----------+----------+------+
status, employee and type are all foreign keys. They link to tables with the following layouts:
users:
+----+-----------+----------+
| id | firstname | lastname |
+----+-----------+----------+
| 1 | John | Doe |
+----+-----------+----------+
| 2 | Dylan | Smith |
+----+-----------+----------+
types:
+----+-----------+
| id | name |
+----+-----------+
| 1 | Annual |
+----+-----------+
| 2 | Quarterly |
+----+-----------+
status:
+----+----------+
| id | name |
+----+----------+
| 1 | Accepted |
+----+----------+
| 2 | Rejected |
+----+----------+
I want the main table to then look like this is
+------------+------------+-----------+--------------+-----------+----------+-----------+
| startdate | enddate | status | employee | cause | duration | type |
+------------+------------+-----------+--------------+-----------+----------+-----------+
| 2018-01-05 | 2018-01-07 | Rejected | John Doe | some text | 3 | Annual |
+------------+------------+-----------+--------------+-----------+----------+-----------+
| 2018-02-03 | 2018-02-04 | Accepted | Dylan Smith | some text | 2 | Quarterly |
+------------+------------+-----------+--------------+-----------+----------+-----------+
I've tried various things I've found on Google as well as SO but I can't get it to come out the way I want it to. I come from a PHP background but I have some experience in SQL, but I am not an expert. I've tried getting the values corresponding to the IDs and saving them in a different table, but I don't know how I can update the table with those returned values:
INSERT into stat
SELECT b.name stat
FROM data a JOIN status b
ON a.status = b.id
This creates a column with the right values in the right order in a table called "stat", like so:
+----------+
| status |
+----------+
| Rejected |
+----------+
| Accepted |
+----------+
This works similarly for the "users" (I also concatenate the first name and last names into a column called "name" in a "user" table. I want to use the concatenated value) and "types" tables. How can I update each respective FK value in the "data" table with their respective values as in the tables above?
Joining from the data table to the three other tables should work here:
SELECT
d.startdate,
d.enddate,
s.name AS status,
CONCAT(u.firstname, ' ', u.lastname) AS employee,
d.cause,
d.duration,
t.name AS type
FROM data d
LEFT JOIN status s
ON d.status = s.id
LEFT JOIN users u
ON d.employee = u.id
LEFT JOIN types t
ON d.type = t.id;
If a given value coming in from one of the joins be missing, and you want to display a placeholder value (instead of the default NULL), then you may use the COALESCE function.
I have two tables users and services and i am try to write a single query that will create a new column skills. The values in the column skills will be the service_title which maps to the service_id stored in user_skills.
Below are the examples of a the tables used:
Table users:
+---------+---------------+----------------+----------------+
| id | user_fname | user_lname | user_skills |
+---------+---------------+----------------+----------------+
| 1 | kiran | bhattarai | 1,2 |
| 2 | sujan | bhattarai | 2,4 |
| 3 | manorath | dad | 1,2,3,4 |
| 4 | bhagawoti | mom | 2,3 |
+---------+---------------+----------------+----------------+
Table services:
+-----------------+------------------+
| service_id | service_title |
+-----------------+------------------+
| 1 | cook |
| 2 | clean |
| 3 | grocessery |
| 4 | teach |
+-----------------+------------------+
Currently i am using this query:
SELECT users.user_fname,
users.user_lname,
(SELECT GROUP_CONCAT(service_title)
FROM `services`
WHERE `service_id` IN (1,2,3,4)) as skills
FROM users
WHERE
id =3;
Result of the above query:
+---------------+----------------+----------------------------------------+
| user_fname | user_lname | skills |
+---------------+----------------+----------------------------------------+
| manorath | dad | cook,clean,grocessery,teach |
+---------------+----------------+----------------------------------------+
Instead of using the IN (1,2,3,4) I tried IN (users.user_skills) because the values in user_skills changes all the time and the result was:
+---------------+----------------+----------------------------------------+
| user_fname | user_lname | skills |
+---------------+----------------+----------------------------------------+
| manorath | dad | cook |
+---------------+----------------+----------------------------------------+
Every time a new service is added i have to add that service_id in the IN (1,2,3,4,new service id) of my query which is not a proper solution. I have already tried using php and another query to do solve this, the disadvantage of doing that is it is slowing down the process. How should i solve this problem in a single query.
You can use FIND_IN_SET() to JOIN the two tables.
SELECT
u.user_fname,
u.user_lname,
GROUP_CONCAT(s.service_title) as skills
FROM users u
LEFT JOIN services s
ON FIND_IN_SET(s.service_id, u.user_skills)
WHERE u.id = 3
Note that a JOIN with a FIND_IN_SET() condition cannot utilize any index. And that can lead to poor performance.
In general it's a bad idea to store relations in a separated string column. See Is storing a delimited list in a database column really that bad?.
You should normalize your design and create a separate table for your many-to-many relation. The table would look like
Table users_services:
+---------+------------+
| user_id | service_id |
+---------+------------+
| 1 | 1 |
| 1 | 2 |
| 2 | 2 |
| 2 | 4 |
| 3 | 1 |
| 3 | 2 |
| 3 | 3 |
| 3 | 4 |
| 4 | 2 |
| 4 | 3 |
+---------+------------+
And the query would be
SELECT
u.user_fname,
u.user_lname,
GROUP_CONCAT(s.service_title) as skills
FROM users u
LEFT JOIN users_services us ON us.user_id = u.id
LEFT JOIN services s ON s.service_id = us.service_id
WHERE u.id = 3
I have 2 tables.
Phonebook:
_________________________________
| id | Photo | Name | Number |
|---------------------------------|
| 1 | abc.jpg | John | 123-45-67 |
|---------------------------------|
| 2 | def.jpg | Sam | 482-34-00 |
|_________________________________|
History:
____________________________________
| id | Name | Date | Type |
|------------------------------------|
| 24 | John | 17.03.2014 | Incoming |
|------------------------------------|
| 25 | Sam | 18.03.2014 | Incoming |
|------------------------------------|
| 26 | Sam | 19.03.2014 | Outgoing |
|____________________________________|
I need to get all columns from History table where id = $id (25 in my case) and get Image column from Phoneboock where History.Name = Phonebook.Name (Sam in my case). Below is the result that I want to get:
______________________________________________
| id | Name | Date | Type | Image |
|----------------------------------------------|
| 25 | Sam | 18.03.2014 | Incoming | def.jpg |
|______________________________________________|
It seems your problem is the SQL to get your data, so use this:
SELECT History.*, Phonebook.Photo
FROM History INNER JOIN Phonebook ON Phonebook.Name = History.Name
AND History.id = $id
You can use JOIN as follows:
SELECT * FROM History INNER JOIN Phonebook WHERE History.name = Phonebook.name
That will give you a join of all the rows. You can customize it more to get what you want. Look at JOIN here for more info
If you are looking for the SQL Select statement, it would look something like this:
SELECT HISTORY.*, PHONEBOOK.Photo FROM HISTORY, PHONEBOOK
WHERE HISTORY.Name = PHONEBOOK.Name AND HISTORY.id='25'
I have two table that I need to combine in a specific way. I need the information in one table displayed once but I need the information in the next table to return every matching data it has. here is my example
user
| id | name |
-------------
| 1 | mike |
| 2 | john |
| 3 | bill |
-------------
class
-----------------
| uid | subject |
-----------------
| 1 | math |
| 1 | English |
| 2 | math |
| 3 | math |
| 3 | English |
-----------------
expected results
--------------------
|name | mike |
---------------------
|subject| math |
| | English |
---------------------
or
--------------------
|name | subject |
---------------------
|mike | math |
| | English |
---------------------
this is my current query
SELECT user.name, class.subject
FROM user
join class on class.uid = user.id
WHERE (user.name like '%mike%')
returns
--------------------
|name | subject |
---------------------
|mike | math |
|mike | English |
---------------------
but I want to remove all name duplicates. can anyone help with this query
You could concatenate the values into a delimited string with a join type function... e.g.
Select u.name, (
select
GROUP_CONCAT(c.subject) FROM classes c where u.id = c.uid
) As subjects
From user u
so you end up with
--------------------
|name | subjects |
---------------------
|mike | math, English |
set #lastname = null;
select case when name = #lastname
then ""
else #lastname := name
end name,
subject
from (select name, subject
from user
join class on id = uid
where name like '%mike%'
order by name) x
FIDDLE
However, as others pointed out in the comments, this is usually done in the application code, not in the SQL. In your loop that processes rows, just check if the name is the same as the previous one, and leave that table field blank. Or use a grid widget that automates grouping for you.
I'm new to relational sql. I'm trying to figure out a query to return the names of customers who have more than one type of account.
customers:
+------------+--------------+
| cid | Name |
+------------+--------------+
| 1 | Bob |
| 2 | John |
| 3 | Jane |
+------------+--------------+
accounts:
+------------+--------------+
| aid | type |
+------------+--------------+
| 1 | Checking |
| 2 | Saving |
| 3 | CD |
+------------+--------------+
transactions:
+------------+--------------+--------------+
| tid | cid | aid |
+------------+--------------+--------------+
| 1 | 1 | 1 |
| 2 | 2 | 1 |
| 3 | 1 | 2 |
| 4 | 2 | 3 |
| 5 | 3 | 1 |
+------------+--------------+--------------+
With these tables, the query should return Bob and John. I'm having some trouble with how to write such a query. More specifically, how do I keep count of how many accounts a customer has and how do I compare if the accounts are different without adding a new column to the table?
Okay, this seems to work in SQL Fiddle with my test data structure. Try it out with your real data structure and see if it gives you what you're looking for.
SELECT name FROM customers c WHERE EXISTS(
SELECT DISTINCT aid FROM transactions
WHERE cid = c.cid
HAVING COUNT(DISTINCT aid)>1
)