show all employees from specific set of stores - php

My job is to cleanse the database from broken store records(records with missing data like a store name or streetname, database example below). However it turns out some of those records have employees linked to them so we can't just delete them.
Question: what kind of query do I need to make sure only the employees of those stores are shown?
I have three tables in which i need to work: user, department and store_users (store_users is a table in which all ID's are packed together to see which user_id belongs to which store_id.)
Example of code
its most likely wrong but its to give some insight in what I am trying to accomplish.(its purely mysql at the moment)
SELECT
*
FROM
gebruiker
WHERE
(SELECT
*
FROM
winkel_adresgegevens
WHERE
winkel_id IN (SELECT
winkel_gebruikers_winkel_id
FROM
winkel_gebruikers)
AND (winkel_naam = '' OR winkel_straat = ''
OR winkel_huisnummer = ''
OR winkel_postcode = ''
OR winkel_plaats = ''));
database example
+--------+---------------+----------+------------+------------------+
|store_id|store_branch_id|store_name|store_street|store_streetnumber|
|-------------------------------------------------------------------|
| 1 | 100 | Jumbo | Hilversum | 14 |
|--------+---------------+----------+------------+------------------|
| 2 | 150 | Lidl | Kerkelanden| 24 |
|--------+---------------+----------+------------+------------------|
| 3 | 105 | | Loosdrecht | |
|--------+---------------+----------+------------+------------------|
| 4 | 200 | Coop | | 14 |
+--------+---------------+----------+------------+------------------+
hence the question: only show employees from the broken records. (the ones with missing data, see store_name, store_street and store_streetnumber)

UPDATE : This is what you want
SELECT *
FROM employees
WHERE store_name IS NULL OR store_street IS NULL OR store_streetnumber IS NULL ;

Related

MySQL get newest data of user from every table

I have 6 tables to store my user data
tbl_user_name
uuid | username | date (unix time)
-----------------------------------------
0 | lisha.s | 1489857236
1 | titami | 1485853232
2 | mathew | 1442853636 <----|> Users can change their username
3 | sandarjun | 1489857239 |> so i need to get the uuid by the
2 | mathew_kar | 1575456274 <----|> newest username which is given
tbl_user_fullname:
uuid | fullname | date (unix time)
-----------------------------------------
0 | Lisha Simonette | 1489857236
1 | Titus Amiran | 1481256345
2 | Mathew Karolina | 1489234455
3 | Sandhya Arjun | 1489857239
0 | Lisha Karolina | 1599999999
tbl_user_website:
uuid | website | date (unix time)
-----------------------------------------
0 | google.com | 1489857236
1 | titusamiran.com | 1489855234
2 | mathewk.net | 1489857432
3 | blod.sandhya.info | 1489857239
tbl_user_birthdate:
uuid | birthdate | date (unix time)
-----------------------------------------
0 | 02-05-1991 | 1489857236
1 | 05-08-1980 | 1489857123
2 | 09-09-1992 | 1489851334
3 | 17-02-1998 | 1489857239
tbl_user_follower:
uuid | follower_uuid
-----------------------
0 | 4
1 | 8
2 | 0
3 | 4
3 | 2
3 | 1
tbl_user_online:
uuid | last_seen (unix time)
-----------------------
0 | 1489855334
1 | 1589851111
2 | 1689857234
3 | 1789834539
i want to collect the uuid, the fullname, the website, the birthdate and the number of followers by a user with a given username. (i need to get the newest uuid of a username because the user can change the username).
The date column is the timestamp when they changes a value. for example in tbl_user_fullname: Lisha Simonette (uuid 0) married Mathew Karolina (uuid 2) so i neet to get the new fullname of Lisha (uuid 0) by the date column. And so on ... for tbl_user_website and tbl_user_birthdate .. even if they dont change their birthday often ;)
From the table tbl_user_online i only need the last_seen timestamp.
The value i give to the query is the username. the username should give out the uuid with which i can query the other tables.
Thank you very much for your help and sorry for my bad english ;)
The below query will resolve the question asked:
SELECT usr.uuid,
ful.fullname,
web.website,
brt.birthdate,
COUNT(fol.follower_uuid)
FROM tbl_user_name usr
JOIN tbl_full_name ful ON ful.uuid = usr.uuid
LEFT JOIN
tbl_full_name ful2 ON ful2.uuid = ful.uuid
AND ful2.time_stamp > ful.time_stamp
JOIN tbl_user_website web ON web.uuid = usr.uuid
LEFT JOIN
tbl_user_website web2 ON web2.uuid = web.uuid
AND web2.time_stamp > web.time_stamp
JOIN tbl_user_birthdate brt ON brt.uuid = usr.uuid
LEFT JOIN
tbl_user_birthdate brt2 ON brt2.uuid = brt.uuid
AND brt2.time_stamp > brt.time_stamp
JOIN tbl_user_follower fol ON fol.uuid = usr.uuid
WHERE usr.username = 'jack_2'
AND ful2.uuid IS NULL
AND web2.uuid IS NULL
AND brt2.uuid IS NULL
GROUP BY
usr.uuid,
ful.fullname,
web.website,
brt.birthdate
This query works by isolating the latest timestamp in a table that shares a common element in a row. In this case the uuid.
Here is the fiddle to see it working.
Here is a fiddle without the username filter
You have a bigger issue that you need to resolve, however. You should not be storing values like you are with timestamps.
I suggest you look into table triggers for update and insert statements. You should have a trigger set up to automatically insert an entry into an audit table that stores this information while keeping your core functioning tables small and orderly.
e.g create a table called tbl_user_name_audit. Have a trigger on tbl_user_name for updates. When a username is updated the previous value is inserted into the tbl_user_name_audit table with a before and after value as well as a timestamp and audit type (INSERT/UPDATE/DELETE).

Return multiple labels for a field with multiple values

I have a function that runs and gets the labels from a lookup table for values stored in a particular table. When there is 1 value it displays correctly. However when there is multiple values it only returns the first one. For example:
Lookup table is
| Tel_No| Tel_type |
--------------------
| 1 | Info |
| 2 | Support |
| 3 | Call |
Main table is
| TelephoneCalls |
------------------
| 1,3 |
| 3 |
| 1,2,3 |
The function I have at the moment which works for matching 1 value is
function getMonitoring($monitoring){
$query = "SELECT Tel_type FROM TelephoneCalls Where Tel_no = '$monitoring'";
$result9 =mysql_query($query) or die(mysql_error());
list($Tel_type) = mysql_fetch_array($result9, MYSQL_NUM);
return $Tel_type;
}
How can I get it to list the values like below
If 1, 3 then display Info, Call
If 3 display Call
If 1, 2, 3 display Info, Support, Call
Thanks for any help!
I guess the comments touched upon it, but you really should change your schema to be more of a many-to-many relationship than using CSV values in the fields. If you can't this query should work:
SELECT telephonecalls, GROUP_CONCAT(tel_type)
FROM lookup_table
LEFT JOIN main_table ON FIND_IN_SET(tel_no , replace(TelephoneCalls,' ', '')) > 0
GROUP BY telephonecalls;
#outputs
+----------------+------------------------+
| telephonecalls | GROUP_CONCAT(tel_type) |
+----------------+------------------------+
| 1,2,3 | Info,Support,Call |
| 1,3 | Info,Call |
| 3 | Call |
+----------------+------------------------+
http://sqlfiddle.com/#!2/194fd/1/0

Comparing two SQL Tables in PHP

I have a SQL table being created daily that is downloaded from a suppliers website,containing product info, that is in csv. I have everything creating alright and all the tables are identical. The problem that I am needing solved is that I need to compare the tables between today and yesterday (table names are the dates in following format mm-dd-yyyy) I need to compare a few different columns for different things.
I need to know all products that are in today's data that weren't in
yesterdays (can be checked by supplier SKU)
I need to know all product that were in yesterday's data that is no
longer in today's
I need to know when the price went up from yesterday's data
I need to know when the price has gone down from yesterday's data
I need to know when a sale has started based on yesterday's data as
well as stopped
These need to show the following labels in the table that will show the changes
regular up
regular down
miscillanious change (description change or change to a fields that aren't a priority)
promo on (discount added from supplier)
promo off (discount taken off by supplier)
delete (no record of the product in new list {probably been deleted})
new item (new record of product in new list)
out of stock
I have been searching everywhere for the answer for these issues and have found stuff that kind of shows me how to do this using union and join but I don't fully understand how to use them based on this scenario.
I have tried different PHP solutions by going through each piece of data and searching for the sku in the new table and vice versa then checking for any changes if they exist in both tables but this is taking a really long time and I have over 200 000 products in these tables. I am hoping that I can do these in less queries and by letting the sql server do more work then the php script.
Thanks for all the help!
Yesterday's Table
__________________________________________________________
| id | price | sale | description | qty | sku |
---------------------------------------------------------
| 1 | 12.50 | 0.00 | description product 1 | 12 | 12345 |
| 2 | 22.99 | 20.99 | describe the problem | 1 | 54321 |
| 3 | 192.99 | 0.00 | description ftw | 5 | 53421 |
| 4 | 543.52 | 0.00 | description | 15 | 45121 |
----------------------------------------------------------
Today's Table
__________________________________________________________
| id | price | sale | description | qty | sku |
---------------------------------------------------------
| 1 | 12.50 | 0.00 | description product 1 | 12 | 12345 |
| 2 | 22.99 | 0.00 | describe the problem | 1 | 54321 |
| 3 | 192.99 | 50.00 | description ftw | 5 | 53421 |
| 4 | 523.99 | 0.00 | description | 15 | 45123 |
----------------------------------------------------------
I need the new table to look like the following
_____________________________________________________________
| id | sku | label | description | price |
-------------------------------------------------------------
| 1 | 54321 | promo off | describe the problem | 22.99 |
| 2 | 53421 | promo on | description ftw | 192.99|
| 3 | 45123 | new item | description | 523.99|
| 4 | 45121 | delete | description | 543.52|
-------------------------------------------------------------
The following is the code I have for the deleted and new items currently. I am using int for the label/status in the example below and just signifying the different numbers.
$deleted = mysql_query("SELECT * FROM `test1`") or die(mysql_error());
while($skus= mysql_fetch_array($deleted))
{
$query = mysql_num_rows(mysql_query("SELECT * FROM `test2` WHERE SKU='".$skus['sku']."'"));
if($query < 1)
{
$tata= mysql_query("INSERT INTO `gday` (Contract_Price, SKU, status) VALUES (".$skus['price'].", ".$skus['sku'].", 1)");
}
}
$deleted = mysql_query("SELECT * FROM `test2`") or die(mysql_error());
while($skus= mysql_fetch_array($deleted))
{
$query = mysql_num_rows(mysql_query("SELECT * FROM `test1` WHERE SKU='".$skus['sku']."'"));
if($query < 1)
{
$tata= mysql_query("INSERT INTO `gday` (Contract_Price, SKU, status) VALUES (".$skus['price'].", ".$skus['sku'].", 2)");
}
}
EDIT:
The Following is the true table that all the data will be going into. I originally didn't want to muddy the water with the large table but by request I have included it.
ID
Status
DiscountDate
Price
Discount
DiscountEndDate
Desc1
Desc2
Desc3
Warranty
Qty1
Qty2
PricingUnit
PriceUpdate
Vendor
Category
UPC
Weight
WeightUnit
Because of the size of your database I could propose you an SQL solution.
When you work with a lot of data, PHP can be slow for several reason.
You can try to do some functions.
You just have to store the status data in an other table. This is the documentation to write a trigger.
http://dev.mysql.com/doc/refman/5.0/en/triggers.html
Becareful if you have a lot of operation on your table I can suggest you to use PostgresSQL instead of mysql because I found it more simple to write function, trigger, ... using PL/sql
EDIT: Just have to write a simple function
I'm working on it at the moment. Think about using select case like in this answer
EDIT: Core function
DELIMITER |
CREATE PROCEDURE export()
BEGIN
(SELECT today.id, today.sku,
CASE today.price
WHEN today.price = yesterday.price THEN 'nothing'
WHEN today.price < yesterday.price THEN 'promo on'
ELSE 'promo off' END AS label
FROM today, yesterday WHERE yesterday.sku = today.sku)
UNION
(
SELECT today.id, today.sku,
'new item' AS label
FROM today LEFT JOIN yesterday ON yesterday.sku = today.sku WHERE yesterday.sku IS NULL)
UNION
(
SELECT yesterday.id, yesterday.sku,
'delete' AS label
FROM yesterday LEFT JOIN today ON today.sku = yesterday.sku WHERE today.sku IS NULL
);
END|
DELIMITER ;
To call just do:
CALL export();
Here is an example of possible core functions. Be careful in this case id could be the same. In the function you'll have to add a personal one in the first column.
If you need performance to display it faster in PHP, think about APC cache

INSERT statement in joined table

I have 3 table:
tblNames:
| id | firstname | lastname |
+------+---------------+--------------+
| 1 | John | Smith |
tblJosbs (this table accepts multiple checkbox value at the same time):
| id | jobs |
+------+-----------------------+
| 1 | Nurse |
+------+-----------------------+
| 2 | Call Center Agent |
+------+-----------------------+
| 3 | Police |
tblNamesJobs (this table is used to JOIN the other 2 tables):
| id | name_id | jobs_id |
+------+-------------+-------------+
| 1 | 1 | 1 |
+------+-------------+-------------+
| 2 | 1 | 2 |
+------+-------------+-------------+
| 3 | 1 | 3 |
All is fine but can someone show me the INSERT statement for the 3rd table I should use to when I will add new information?
For example add record that John Smith is a Call Center Agent
insert into tblNamesJobs (name_id,jobs_id )
values (
select id from tblNames where
firstname='John'
and lastname='Smith' limit 1
,
select id from tblJosbs where jobs='Call Center Agent' limit 1
);
If you are already depending on tauto increment..you can get the lastinserid, depending on your adapter.
eg. mysql_insert_id
for PDO we can use --PDO::lastInsertId.
so you will have id's of earlier inserted tables, that you can save in the new one.
INSERT INTO tblNamesJobs (name_id, jobs_id) VALUES (XXXX,YYYY)
That is assuming the table's id is auto-incrementing.
It should be noted that both the name_id and jobs_id columns in the "joiner" table should be foreign keys to the respective columns in the other table.
Edit - Valex's answer goes into more detail about what to do if you don't already have the id values.
If possible, I would recommend using some sort of framework that would handle the "joiner" table for you.

Show database entries separated by comma

I have one field in the backend, where I input IDs separated by comma - ID1, ID2, ID3....These are videos in fact. All ids are stored in the field product_videos in the database (as they are typed).
How can I echo these id's on the frontend so they all show for the product?
Storing comma separated data in one data field is a bad idea. It is a real pain to manipulate, so you should really consider revising your db structure.
You haven't shown your data structure, so I'll give a basic example and then explain how it can be improved. My example assumes product_videos is linked to particular users:
table: `users`
| user_id | user_name | product_videos |
|---------|-----------|----------------|
| 1 | User1 | 1,2,3,4,6,7 |
| 2 | User2 | 5 |
You would maybe run a query
SELECT `product_videos` FROM `users` WHERE `user_name` = 'User1'
This would give you one row, with a comma separate value - you would then need to use something like PHP's explode() to convert it into an array and then loop through that array. That is a very bad method (and it will only become harder as you try to do more advanced things).
Instead, it would be easier to use a link table. Imagine:
table: `users`
| user_id | user_name |
|---------|-----------|
| 1 | User1 |
| 2 | User2 |
table: `videos`
| video_id | user_id |
|-----------|---------|
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 1 |
| 5 | 2 |
| 6 | 1 |
| 7 | 1 |
In this example, each video is a separate row in a db table (and each video is linked to an existing user). Each row is readily able to be handled independently. This makes it really easy to handle extra data for each video, such as a title, runtime length, date of uploading, etc.
You would then need to run a JOIN query. e.g.
SELECT `videos`.`video_id` FROM `videos`
INNER JOIN `users` ON `users`.`user_id` = `videos`.`user_id`
WHERE `users`.`user_name` = 'User1'
In PHP, you would do something like:
$q = mysql_query("SELECT `videos`.`video_id` FROM `videos` INNER JOIN `users` ON `users`.`user_id` = `videos`.`user_id` WHERE `users`.`user_name` = 'User1'");
while ($row = mysql_fetch_assoc($q)) {
echo "VIDEO ID = " . $row["video_id"] . "<br/>";
}

Categories