Big Mysql Query (Join counts in the result and modify a string) - mysql

I am brand new to mysql so please excuse my level of knowledge here, and feel free to direct me in a better direction if what I am doing is out of date.
I am pulling information from a database to fill in a php page.
My tables:
Server:
|ServerID (int) | ArticleID (int) | locationID (int) |
| 1 | 46 | 55 |
| 2 | 11 | 81 |
| 3 | 81 | 46 |
| 4 | 55 | 11 |
| 5 | 81 | 99 |
| 5 | 11 | 52 |
Article:
|ArticleID (int) | Name (varchar) | Typ (int) |
| 46 | domain | 0 |
| 81 | root-server | 1 |
| 55 | vserver | 2 |
| 11 | root-server2 | 1 |
Location:
|LocationID (int) | location (varchar) |
| 46 | 1-5-15-2 |
| 81 | 1-5-14-2 |
| 55 | 2-25-1-9 |
| 11 | 21-2-5-8 |
| 99 | 17-2-5-8 |
| 52 | 1-8-5-8 |
Result:
|location (int) | name (varchar) | count (int) |
| 1 | root-server | 1 |
| 1 | root-server2 | 2 |
| 17 | root-server | 1 |
The location in the result is the first number block of the location in the location table (1-5-15-2 -> 1, 1-8-5-8 -> 1, 21-2-5-8 -> 21, 17-2-5-8 -> 17).
The count is the sum of all servers with the same name and the same first location block.
Do anyone think its possible to get this result in only one query?
Thanks for any answer!

Check this
SELECT SUBSTRING_INDEX(location, '-', 1) as LID,Article.Name,Count(*) as Count
from Location join Server
on Server.locationID=Location.locationID
join Article on Article.ArticleID=Server.ArticleID
group by LID,Article.ArticleID ;
DEMO

Please give this a shot:
SELECT
s.locationID as id, a.name, count(*) as count
FROM
`Server` s
LEFT JOIN
`Article` a ON s.ArticleID = a.ArticleID
GROUP BY s.locationID, a.name

something like this should work
select
s.location_id as location, a.name, count(location) as count
from
server as s, article as a
where
s.articleID = a.articleID
group by location, a.name

Related

MultiColumn where IN in mysql

I am running a query like this -
UPDATE table
SET eligible=1
where (name, age) in [["john",29],["mark",28],["jim",20]]
table structure is like this
name age eligible
mark 28 null
john 29 null
Max 20 null
But mysql throws the wrong syntax error, can anyone confirm that this is allowed in mysql?
SELECT * FROM my_table ORDER BY id LIMIT 10;
+----+-------+--------+
| id | type | count |
+----+-------+--------+
| 1 | green | 4 |
| 2 | blue | 3 |
| 3 | blue | 443792 |
| 4 | green | 455353 |
| 5 | blue | 445389 |
| 6 | blue | 360885 |
| 7 | green | 468258 |
| 8 | red | 258636 |
| 9 | blue | 388405 |
| 10 | green | 166117 |
+----+-------+--------+
SELECT *
FROM my_table
WHERE (type,count) IN (('red',1000),('green',2000),('blue',3000)) ORDER BY id LIMIT 100
-> ;
+--------+-------+-------+
| id | type | count |
+--------+-------+-------+
| 137339 | blue | 3000 |
| 339554 | red | 1000 |
| 947445 | green | 2000 |
+--------+-------+-------+
Note that MySQL can have problems utilising indexes when using this method. For that reason, it can prove more efficient to write the query out 'long-hand'.
If you're on an older version of MySQL, or an alternative way is to separate out the where statements:
UPDATE table
SET eligible=1
WHERE
(name = "john" AND age = 29) OR
(name = "mark" AND age = 28) OR
(name = "jim" AND age = 20)

MySQL Join Query without duplicate values

invoice table
SELECT id, fname, gtotal, `date` FROM invoice WHERE id = 1;
| id | fname | gtotal | date |
|----|---------|--------|-----------------------|
| 1 | Brandon | 860 | May, 11 2016 00:00:00 |
invoice_contents table,
SELECT * FROM invoice_contents WHERE invoice_id = 1;
| id | invoice_id | item | price | quantity | discount | total |
|----|------------|------------|-------|----------|----------|-------|
| 1 | 1 | Dextrose | 10 | 10 | 5 | 95 |
| 2 | 1 | Nescaine | 20 | 30 | 10 | 540 |
| 3 | 1 | Anticavity | 30 | 10 | 25 | 225 |
This JOIN query
SELECT invoice.id, invoice.fname, invoice_contents.item,
invoice_contents.price, invoice_contents.quantit,
invoice_contents.discount, invoice_contents.total,
invoice.gtotal
FROM invoice_contents
INNER JOIN invoice ON invoice_contents.invoice_id=1 AND invoice.id=1;
gives this result.
| id | fname | item | price | quantity | discount | total | gtotal |
|----|---------|------------|-------|----------|----------|-------|--------|
| 1 | Brandon | Dextrose | 10 | 10 | 5 | 95 | 860 |
| 1 | Brandon | Nescaine | 20 | 30 | 10 | 540 | 860 |
| 1 | Brandon | Anticavity | 30 | 10 | 25 | 225 | 860 |
I need this result.
| id | fname | item | price | quantity | discount | total | gtotal |
|----|---------|------------|-------|----------|----------|-------|--------|
| 1 | Brandon | Dextrose | 10 | 10 | 5 | 95 | 860 |
| | | Nescaine | 20 | 30 | 10 | 540 | |
| | | Anticavity | 30 | 10 | 25 | 225 | |
I am just a beginner in MySQL. I have been trying from this morning to get this kind of output by experimenting on different combinations please help me out.
#Rex, Your select is correct. You should make desired output using some script e.g. PHP.
try this in SQL:
in this Query i save everytime fname in a variable is not equal and at the next row i compare it and return a empty string is it equal. and the same for gtotal.
the cross join is only to initialize the variables.
in this case it is important that the rows are order by fname to ensure that the same name is behind each other
SELECT
invoice.id,
IF(#last_fname = invoice.fname, '', (#last_fname:=invoice.fname)) as fname,
invoice_contents.item,
invoice_contents.price,
invoice_contents.quantity,
invoice_contents.discount,
IF(#last_gtotal = invoice.gtotal, '', (#last_gtotal:=invoice.gtotal)) as gtotal
FROM invoice_contents
INNER JOIN invoice ON invoice_contents.invoice_id=1 AND invoice.id=1
CROSS JOIN ( select #last_fname := '' , #last_gtotal := '' ) AS parameter
ORDER BY invoice.fname;
Sample
MariaDB [bb]> SELECT
-> invoice.id,
-> IF(#last_fname = invoice.fname, '', (#last_fname:=invoice.fname)) AS fname,
-> invoice_contents.item,
-> invoice_contents.price,
-> invoice_contents.quantity,
-> invoice_contents.discount,
-> IF(#last_gtotal = invoice.gtotal, '', (#last_gtotal:=invoice.gtotal)) AS gtotal
-> FROM invoice_contents
-> INNER JOIN invoice ON invoice_contents.invoice_id=1 AND invoice.id=1
-> CROSS JOIN ( SELECT #last_fname:='' , #last_gtotal:='' ) AS parameter
-> ORDER BY invoice.fname;
+----+---------+------------+-------+----------+----------+--------+
| id | fname | item | price | quantity | discount | gtotal |
+----+---------+------------+-------+----------+----------+--------+
| 1 | Brandon | Dextrose | 10.00 | 10 | 5.00 | 860.00 |
| 1 | | Nescaine | 20.00 | 30 | 10.00 | |
| 1 | | Anticavity | 30.00 | 10 | 25.00 | |
+----+---------+------------+-------+----------+----------+--------+
3 rows in set, 1 warning (0.00 sec)
MariaDB [bb]>

sql select query from two different tables WHERE active=1

i try select all columns from two different tables WHERE active = 1
i have 2 tables table_pro and table_basic,
sql:"select * from table_basic,table.name";
and 2 condition:
WHERE active = 1
WHERE table_pro.id = table_basic.name.id
how to make it correctly
Here is table_pro
+----+--------+---------+-----------+
| id | people | rooms | active |
+----+--------+---------+-----------+
| 1 | 5 | 10 | 0 |
| 2 | 12 | 17 | 0 |
| 3 | 21 | 38 | 1 |
+----+--------+---------+-----------+
Here is table_basic
+---------+-------+---------+------------+----------+
| name_id | name | balance | title | time |
+---------+-------+---------+------------+----------+
| 1 |shop | 100 | failed | 15:10:20 |
| 2 |factory| 75 | error | 15:10:20 |
| 3 |studio | 25 | timed_out | 15:10:20 |
+---------+-------+---------+------------+----------+
I'd like to have this output result only rows (from of all columns) with status active = 1
+-----+-------+----- --+--------+-------+----------+---------+--------+
| id | people| rooms | name |balance| title | time | active |
+-----+-------+--------+--------+-------+----------+---------+--------+
| 3 | 21 | 38 | studio |25 | timed_out| 15:10:20| 1 |
+-----+-------+--------+--------+-------+----------+---------+--------+
Thanks
SELECT A.id, A.people, A.rooms, B.name, B.balance, B.title, B.time, A.active
FROM
table_pro AS A
JOIN
table_basic AS B
ON
A.id = B.name_id
WHERE
A.id = 3
SELECT table_pro.*, table_basic.*
FROM table_pro
INNER JOIN table_basic
ON table_basic.name_id = table_pro.id
WHERE table_pro.active = 1

solve mysql query

Today I have been asked a question by an interviewer that stated
we have three tables named as table A, B, and C.
Those tables are like this
A B C
------------------ -------------------------- ----------------------------
| ID | ProjectID | | ID | LocationID | aID | | ID | points | LocationID |
------------------ -------------------------- ----------------------------
| 1 | 15 | | 1 | 131 | 1 | | 1 | 123333 | 131 |
| 2 | 15 | | 2 | 132 | 1 | | 2 | 123223 | 132 |
| 3 | 15 | | 3 | 133 | 1 | | 3 | 522 | 211 |
| 4 | 12 | | 4 | 134 | 2 | | 4 | 25 | 136 |
------------------ | 5 | 136 | 2 | | 5 | 25 | 133 |
| 6 | 137 | 3 | | 6 | 25 | 134 |
| 7 | 138 | 1 | | 7 | 25 | 135 |
-------------------------- ----------------------------
now he told me to write a query that sums the points of those locations whose project is 15.
First i wrote the query to get ID's from table A like this
SELECT ID from A where projectID = 15
then i pass this result in table b query just like this
SELECT LocationID FROM B WHERE aID IN ( SELECT ID from A where projectID = 15 )
Then i calculate the sum of these locations just like this
SELECT SUM(points) from C where LocationID IN(SELECT LocationID FROM B WHERE aID IN ( SELECT ID from A where projectID = 15))
My Result is fine and query is correct. But he rejected my answer by saying that this nested IN Clause will slow down the whole process as when we have thousands of records.
Then he gave me another chance to review my answer but i couldn't figure it out.
Is there anyway to optimize this or is there some other way to do the same.
Any help? Thanks
Try this it may solve your problem.
Select SUM(C.points) FROM C JOIN B ON C.LocationID = B.LocationID JOIN A ON B.aID = A.ID where A.ProjectID = 15 GROUPBY A.ProjectID
Try with this....i hope it will work
select sum(c.points) as sum_points
from A a,B b,C c where
a.ID=b.aID and
b.LocationID=c.LocationID
and a.projectID=15

MySQL Select Column if Column in another table is zero

My issue is mostly that im not sure how to word what I need in a search.
mysql> SELECT * FROM `accounts`;
+----+--------+---------+----------+
| id | status | oplevel | username |
+----+--------+---------+----------+
| 10 | 1 | 0 | root |
| 11 | 1 | 1 | Xylex |
| 12 | 1 | 16 | Anubis |
| 13 | 0 | 16 | Kami |
| 14 | 1 | 16 | Zorn |
+----+--------+---------+----------+
mysql> SELECT * FROM `networks`;
+-----------+-----------+-------------+-----------------+
| networkid | accountid | networkname | serveraddress |
+-----------+-----------+-------------+-----------------+
| 1 | 10 | Fakenet | irc.fakenet.org |
| 2 | 10 | Undernet | irc.under.net |
| 3 | 12 | Takenet | irc.takenet.com |
| 4 | 13 | Examplenet | irc.example.org |
+-----------+-----------+-------------+-----------------+
I have this accounts table and this networks table
I need a single query that will return the address of the IRC network, ONLY IF the corresponding account id status column is 1 (enabled)
Ive been searching for hours.
What Do?
looks like a simple join to me:
select serveraddress from accounts join networks on id=accountid and id=YOUR_ACCOUNT_ID_HERE
Or
select serveraddress from networks where accountid=YOUR_ID and exists(select * from accounts where id=accountid and status)
Many ways to go about this..
select serveraddress from networks, accounts where networks.accountid = accounts.id and accounts.satus=1;
Is it what you're looking for?
I've updated the query to place account id.
select acc.id, acc.username, nw.serveraddress from accounts acc join networks nw on acc.id = nw.accountid where acc.status == 1 and acc.id=XXX