Query date from same column with several conditions - mysql

I want to do a query to see when a client is disconnected, between January and February, by a cable company and if they got connect again until 7 days after the disconnection.
My table would be something like this:
+---------+----------+------------+------------+
| client | ID_Order | Work_Order | Date_Order |
+---------+----------+------------+------------+
| Client1 | 123AB | Disconnect | 20/01/2017 |
| Client1 | 234EA | Connect | 22/01/2017 |
| Client2 | 242FA | Connect | 30/01/2017 |
| Client3 | 244FE | Disconnect | 30/01/2017 |
| Client2 | 301EA | Disconnect | 10/02/2017 |
| Client4 | 355AD | Disconnect | 20/02/2017 |
| Client4 | 368AD | Connect | 25/02/2017 |
| Client5 | 401AD | Connect | 05/03/2017 |
| Client6 | 440AD | Disconnect | 15/03/2017 |
+---------+----------+------------+------------+
And I want to transform the previous table in a table like this: one row per client, with the connect order and disconnect order in 2 different columns
+---------+-----------------+-------------+--------------+------------+
| client | ID_Order_Discon | Date_Discon | ID_Order_Con | Date_Con |
+---------+-----------------+-------------+--------------+------------+
| Client1 | 123AB | 20/01/2017 | 234EA | 22/01/2017 |
| Client4 | 355AD | 20/02/2017 | 368AD | 25/02/2017 |
+---------+-----------------+-------------+--------------+------------+
My problem:
1- How make the query inside the same columns (Date_Order), to choose the clients that where connected after 7 days the disconnection. Guess need to use DATEDIFF()?
2- how to put the orders of the same client in 2 different columns? Guess I have to do an IF()/CASE () and a join ()?

To Combine both table you can use:
select c1.client, cq.ID_Order ID_Order_Discon , c1.Date_Order as Date_discon, c2.ID_Order ID_Order_Con, c2.Date_order Date_Con
from table c1 join table c2 on t1.client = t2.client and t1.work-order = 'disconnect' and t2.work_order = 'Connect'
and for the frst question you can use where DATEDIFF(c1.date_order,c2.dateOrder)>7

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.

SQL join: selecting last records from duplicates

I am working on python project "Linux Server Monitor". When you load monitoring website you create your servers and table look like this:
Servers:
+-----------+-----------+---------+-------------+
| server_id | auth_code | user_id | server_name |
+-----------+-----------+---------+-------------+
| 0 | xyz123 | 1 | My Server 1 |
| 1 | aabb | 45 | BlaBlaUser |
| 2 | asdfh1 | 1 | My Server 5 |
+-----------+-----------+---------+-------------+
After the server is created, you start python script and it starts to upload monitoring data to this table (where all data is stored, from all users):
Monitoring Data:
+----+-----------+---------+---------+------------+-----------------+------------------+
| id | auth_code | user_id | os_name | os_version | external_ip | some_other_table |
+----+-----------+---------+---------+------------+-----------------+------------------+
| 0 | aabb | 45 | Ubuntu | 16.04 | 77.88.99.100 | dynamic data |
| 1 | aabb | 45 | Ubuntu | 16.04 | 77.88.99.100 | dynamic data 2 |
| 2 | aabb | 45 | Ubuntu | 16.04 | 10.10.10.10 | dynamic data 3 |
| 3 | xyz123 | 1 | Fedora | 27 | 92.94.95.99 | different data 1 |
| 4 | xyz123 | 1 | Fedora | 27 | 92.94.95.99 | different data 2 |
| 5 | xyz123 | 1 | Fedora | 27 | 92.94.95.99 | different data 3 |***
| 6 | asdfh1 | 1 | CentOS | 7 | 5.5.5.5 | some new data 1 |
| 7 | asdfh1 | 1 | CentOS | 7 | 5.5.5.5 | some new data 2 |
| 8 | asdfh1 | 1 | CentOS | 7 | 2.2.2.2 | some new data 3 |###
+----+-----------+---------+---------+------------+-----------------+------------------+
I want to join first and second table to show user "important" information like this:
Your Active Servers:
+-----------+-------------+---------+------------+-----------------+
| server_id | server_name | os_name | os_version | external_ip |
+-----------+-------------+---------+------------+-----------------+
| 0 | My Server 1 | Fedora | 27 | 92.94.95.99 |***
| 2 | My Server 5 | CentOS | 7 | 2.2.2.2 |###
+-----------+-------------+---------+------------+-----------------+
If I join first and second table by user_id it will load duplicates too but I want only last inserted record of that particular user's server. In this case on last record "external_ip" of one server changed but other one remained the same (marked with *** and ###).
you could use an inner join on subselect for the max id for user, server on monitorig
select s.server_id, s.server_name, m.os_name, m.os_version, m.external_ip
from servers s
inner join Monitoring m on m.user_id = s.user_id and s.auth_code = m.auth_code
inner join (
select max(id) max_id, user_id, os_name, os_version
from Monitoring
group by user_id, os_name, os_version
) t on t.max_id = m.id
where user_id = 1

How do I get information from multiple MySQL tables?

I'm working on a way to keep track of physical connections between servers/switches in multiple racks. I set up my database so it is like this:
mysql> show tables;
+----------------------+
| Tables_in_System |
+----------------------+
| connections |
| racks |
| servers |
+----------------------+
mysql> select * from racks;
+----+-------------+-------------+----------+
| id | rack_number | rack_height | location |
+----+-------------+-------------+----------+
| 2 | 7430 | 43 | xxx |
| 3 | 7431 | 43 | xxx |
| 4 | 7432 | 43 | xxx |
+----+-------------+-------------+----------+
mysql> select * from servers;
+----+-------------+---------------+-----------------+---------------+
| id | server_type | rack_location | server_unit_loc | server_height |
+----+-------------+---------------+-----------------+---------------+
| 1 | Server 1 | 7430 | 2 | 3 |
| 2 | Cisco 2960 | 7431 | 1 | 1 |
| 3 | Server 2 | 7431 | 9 | 1 |
| 15 | Server 3 | 7432 | 27 | 2 |
| 16 | Cisco 2248 | 7432 | 29 | 1 |
+----+-------------+---------------+-----------------+---------------+
rack_location refers to the numbered racks in the first table.
server_unit_loc is the placement of the server in the rack, 1 being the top, 43 would be the bottom. And server_height is just how tall the server is.
mysql> select * from connections;
+----+----------+----------+------------+------------+---------+---------+------------+
| id | rack_id1 | rack_id2 | server_id1 | server_id2 | port_s1 | port_s2 | cable_type |
+----+----------+----------+------------+------------+---------+---------+------------+
| 1 | 7430 | 7430 | 2 | 1 | J01 | J08 | RJ-45 |
| 2 | 7430 | 7431 | 2 | 3 | J03 | J08 | RJ-45 |
| 3 | 7430 | 7432 | 2 | 15 | J02 | J09 | SFP+ |
+----+----------+----------+------------+------------+---------+---------+------------+
rack_id's again (I realize now these are probably pointless...) server_id1 & 2 are the id's from the servers table. ports_1&2 correlate to the jack the cable is plugged in. This is an internal system we use, so J01 means it is the first jack on the server, and it plugs into the 8th(J08) port on the connecting server.
The end goal here is to be able to quickly see how many servers are connected to any chosen server and also the details about that connection info. In this example I connected the Cisco 2960 to multiple servers in different racks.
+What kind of query would I have to put in to return all the servers that are connected to the Cisco (2). I'd like to be able to specify just the server_id# and it would go to the different tables and get all the information such as which rack it's in, it's type, and the height of the server
Cisco2960 7430 A01 J01 --> Server1 7430 A02 J08 "RJ-45"
Cisco2960 7430 A01 J03 --> Server2 7431 A09 J08 "RJ-45"
Cisco2960 7430 A01 J02 --> Server3 7432 A27 J09 "SFP+"
Something like that...^
Thanks! Also if you have a better idea of how to go about accomplishing this I'd love to hear everyone's thoughts.
You would need to create query that joins the related information together.
Think of label S being (source server). Label T being (target server).
Ex.
SELECT S.server_type, S.rack_location, CONCAT('A0',S.server_unit_loc), B.port_s1,T.server_type, T.rack_location, CONCAT('A0',T.server_unit_loc), B.port_s2,B.cable_type FROM servers S
JOIN connections B ON B.server_id1 = S.id
JOIN servers T ON B.server_id2 = T.ID
WHERE S.id = 2
I agree with one of the comments. You could normalize things (rid some redundant rack information).

create VIEW in mysql from two tables

I have a table with users for my mail server. This table for imap authenication in dovecot:
+-------------+------------------+-------------------+------------------+------+------+---------------------------------------+--------+---------+---------------------------+
| user_name | domain_name | passwd | pwd_hash | uid | gid | mailbox_basepath | enable | quota | desc_rec |
+-------------+------------------+-------------------+------------------+------+------+---------------------------------------+--------+---------+---------------------------+
| logistic | piduna.pp.ua | loG-1990M | _no_hash_passwd_ | 2000 | 2000 | /home/maildir/piduna.pp.ua/ | 1 | 2048000 | box for logistic |
| 1c | piduna.pp.ua | 1c_user_1c | _no_hash_passwd_ | 2000 | 2000 | /home/maildir/piduna.pp.ua | 1 | 2048000 | Denisyuk V.V. |
| admin | piduna.pp.ua | AAddMmM1N | _no_hash_passwd_ | 2000 | 2000 | /home/maildir/piduna.pp.ua | 1 | 2048000 | Admin |
| al.service | piduna.pp.ua | Alumo_Serv4321 | _no_hash_passwd_ | 2000 | 2000 | /home/maildir/piduna.pp.ua | 1 | 2048000 | Alumo Service |
I need to create table with two columns. First column, all#piduna.pp.ua. Second column it is all my email accounts. In one table, I know how make concatenation from user_name and domain_name. Look:
CREATE VIEW `forwardings_all_view` AS select lcase(concat(`users`.`user_name`,'#',`users`.`domain_name`)) AS `email_fqn` from `users` where (`users`.`enable` = 1)
But, how to add in it VIEW, second column: all#piduna.pp.ua.
Like that:
+------------------------------+-------------------------------------------------+
| email_fqn | source |
+------------------------------+-------------------------------------------------+
| .logistic#piduna.pp.ua | all#piduna.pp.ua |
| 1c#piduna.pp.ua | |
| admin#piduna.pp.ua | |
| al.service#piduna.pp.ua | |
Try this:
create view first_user as
select user_name from users where enable limit 1;
create view forwardings_all_view as
select lcase(concat(a.`user_name`,'#',a.`domain_name`)) AS `email_fqn`,
if(b.user_name is null, '', 'all#piduna.pp.ua') `source`
from `users` a
left join first_user b on a.user_name = b.user_name
where a.`enable` = 1;
fiddle

SQL INSERT INTO query syntax

I am trying to run an MySQL query to copy over data from an old table (ps__product_review/rate) to a new table (ps_product_comment/grade) based on review ID (id_product_comment). But I am a bit lost on the SQL query, this is what I have but keep getting errors.
INSERT INTO ps_product_comment [(grade)]
SELECT rate
FROM ps__product_review
[WHERE ps__product_review.id_product_comment=ps_product_comment.id_product_comment];
Can anyone help write the correct query?
Edit:Essentially I am trying to populate the Grade column in the new table below.
Old table (ps__product_review)
+--------------------+----------+-----+
| id_product_comment | Comment | Rate|
+--------------------+----------+-----+
| 1 | Good | 2 |
| 2 | Great | 5 |
| 3 | OK | 3 |
| 4 | Brill | 4 |
| 5 | OK | 3 |
| 6 | Average | 2 |
| 7 | Bad | 1 |
+--------------------+----------+-----+
New Table (ps_product_comment)
+--------------------+----------+-------+
| id_product_comment | Comment | Grade |
+--------------------+----------+-------+
| 1 | Good | |
| 2 | Great | |
| 3 | OK | |
| 4 | Brill | |
| 5 | OK | |
| 6 | Average | |
| 7 | Bad | |
+--------------------+----------+-------+
If you want to update table with data from another table, use UPDATE with JOIN
UPDATE ps_product_comment
JOIN ps__product_review
ON ps__product_review.id_product_comment = ps_product_comment.id_product_comment
SET ps_product_comment.grade = ps__product_review.rate;
Remove the square brackets and I think you are missing the JOIN(since you are using that in your where clause):
INSERT INTO ps_product_comment (grade)
SELECT rate
FROM ps__product_review inner join ps_product_comment on
ps__product_review.id_product_comment=ps_product_comment.id_product_comment;