Create a table from max and min values in another - mysql

I have table with Name|ValueA|ValueB.1|ValueB,2 where Name is not unique.
I want to extract the B.1 and B.2 values for the low and high A vales for each name.
Bob|1|200|205
Bob|2|500|625
Bob|7|450|850
Bob|3|644|125|
Ann|4|120|120
Ann|8|451|191
Ann|9|145|982
I want a new table with unique names with high and low ValueA, ValueB.1, ValueB.2
Bob|1|7|200|450|205|850
Ann|4|9|120|145|120|982
I remember there is some way to use min/max but am not sure how to set up the query to extract the new table.

INSERT newtable (Name, ValueA, ValueB.1, ValueB.2)
SELECT Name,MAX(ValueA),MIN(ValueA),MAX(ValueB.1),MIN(Value B.1),
MAX(ValueB.2),MIN(ValueB.2)
FROM oldtable GROUP BY Name
Should do the trick.

Assuming that values of A are distinct (at least within a name):
INSERT
INTO newtable
SELECT name, mmin.a, mmax.a, mmin.b1, mmin.b2, mmax.b1, mmax.b2
FROM (
SELECT name, MIN(a) mina, MAX(a) maxa
FROM mytable
GROUP BY
name
) md
JOIN mytable mmin
ON (mmin.name, mmin.a) = (md.name, md.mina)
JOIN mytable mmax
ON (mmin.name, mmin.a) = (md.name, md.maxa)

Related

Mysql query insert into only if select count > n

I have 2 queries:
SELECT COUNT(*) FROM a WHERE id = 1
//if row == 1
INSERT INTO a VALUES(fielda) VALUES('value')
Is there a way to merge these two queries into one? I tried with 'IF (count> 0, ..)' and similar, but the query is incorrect.
This involves inserting a new record into the table, taking care not to exceed a pre-set number of records for each field.
In theory it should be similar to an INSERT IF ...
Edit:
#Barmar I tried but I think I did not understand what you wrote (in fact I made a mistake in the query), I try to answer like this:
THE QUERY AFTER YOUR RESPONSE:
INSERT INTO table1 SELECT MAX(id) FROM table1 WHERE field1 = (SELECT id from a WHERE f = field2) HAVING COUNT(*) = 1 (all fields request) VALUES (all values request)
//field1 = id from table2
//field2 = id from another table: associative value
//ORIGINAL QUERY
//FIRST COUNT:
SELECT COUNT(*) from table1 WHERE field1 = (SELECT id FROM table2 WHERE f = field2)
//AFTER THE INSERT:
INSERT INTO table1 (all fields request) VALUES (all values request)
I came to mind this example I try to show you:
TABLE PLAYER: fields(ID, TEAMID, NAME) => (id=int, teamid=int associate to table team, name=varchar)
TABLE TEAM: fields(ID NAME) => (id=int, name=varchar)
Suppose that the players in a team are maximum 20, so you expect maximum 20 records associated by the player table for the same teamid value, or at least this is what we humans think, because for the computer can also be infinite. I was looking for a way to allow the insertion only in the case in which it is actually permissible to insert records, in this case the condition is that in the players table there are less than 21 records per team.
You can use INSERT ... SELECT, and put the condition in the SELECT query.
INSERT INTO player (teamid, name)
SELECT #teamid, #playername
FROM DUAL
WHERE (SELECT COUNT(*) FROM player
WHERE teamid = #teamid) < 20
DUAL is a dummy table when you need to select literal data, but need to include other clauses in the query.

MySQL insert into table with a set of values

I need to insert a table with some values (eg: 'NDA' in this case). This seems to work well if I have just one value to be inserted. I have around a dozen of similar values, is there a was i can tweak this query to insert say { 'NDA', 'SDM', 'APM' } values. Was curious to know if it can be done without a stored procedure or copy pasting the same statements over and changing the values.
INSERT IGNORE INTO customer_feature (customer_id, feature)
SELECT c.id, 'NDA' FROM
customer as c
where c.edition = 'FREE_TRIAL';
Reference: mysql -> insert into tbl (select from another table) and some default values
Is this what you want?
INSERT IGNORE INTO customer_feature(customer_id, feature)
select c.id, f.feature
from customer c cross join
(select 'NDA' as feature union all select 'SDM' union all select 'APM'
) f
where c.edition = 'FREE_TRIAL';

SQL select values from joined table where value and value appears

I have this MySQL tables:
station (id, name)
station_track (id, id_station, id_track)
track (id, name)
and I'd like to get all the tracks that contains station A and station B... I just can't figure it out :S I tried like this:
SELECT track.name
FROM track, station_track , station
WHERE station.id = station_track.id_station
AND track.id = station_track.id_track
AND (station.name = 'first' AND station.name = 'second')
It doesn't work... I guess I can't use AND for same column values.
SOLVED:
SELECT proge.ime FROM postaje, postaje_proge, proge
WHERE postaje.id=postaje_proge.ID_postaje AND proge.ID=postaje_proge.ID_proge
AND postaje.ime_postaje in ("AP Mlinska","City Center")
GROUP BY proge.ime
HAVING count(proge.ime)=2
tnxx guys for help!
Your final condition, (station.name="first" AND station.name="second"), is checking that one variable is equal to two different values at the same time which will never evaluate to true.
If you want to find all stations with the names first or second, you need to use an OR statement.
SELECT track.name FROM track, station_track , station
WHERE station.id=station_track.id_station
AND track.id=station_track.id_track
AND (station.name="first" OR station.name="second")
Assuming you want tracks linked to both stations A and B, try:
SELECT t.name
FROM track t
JOIN station_track st on t.id=st.id_track
JOIN station s on s.id=st.id_station and s.name in ('first','second')
GROUP BY t.name
HAVING count(distinct s.name)=2
You will have to do a bit of thinking and redesign your tables. If you want to match a field to a list of values you can use the 'in' operative
i.e
SELECT * FROM station_track WHERE id_track in (1, 2, 3, 4);
The above will return all records matching any of the values in the list. So, think about how you could take advantage of this and redesign your schema.

Insert new row with specific values

In 1 table I need to insert specific rows with specific values, according to other tables values.
UPDATE item_properties2 AS P
INNER JOIN items ON items.id = P.item
INNER JOIN item_groups ON item_groups.idp = items.group_id
SET P.nr = '0'
WHERE P.type = 1140614900 AND items_groups.idp = '1140503406';
This updates the table. But what I need is basically.
(id, type, item, value, shows, nr) VALUES
(78173, 1336983282, 1352706945, 'test Laisvai pastatomas Sharp', 0, 1)
item_properties2.Id - just row id,
item_properties2.type - connect to item_property_groups2.id ,
'item_properties2.item' this connects to item.id ,
item.id have another column which is item.group_id ,
item.group_id is connected to item_groups.id which have another column naked item_groups.idp .
I need to only select items_groups.idp = '1140503406' . And basically i it should add rows in item_properties2 with with specific type value which i entered and only to models with specific item_properties2. item accord to item_groups.idp . I don't know how to do it.
there are some ways to insert a bulk of data from 2 tables into a newer table.
this can be done like this:
INSERT INTO item_properties2 (id, type, item, value, shows, nr)
SELECT Yid, Ytype,Yitem,Yvalue, Yshows, Ynr
FROM items
INNER JOIN item_groups ON item_groups.idp = items.group_id
WHERE items_groups.idp = '1140503406'
Instead of using the VALUES tag, you will now call for a specific select statement. you only need to change the Y values above into your own column names.
Or you could place your input into a stored procedure
the above query will run over your 2 tables and will insert the values that go with the where statement into the 3th table.
CREATE PROCEDURE sInput
( #val1 int, #val2 int, #val3 varchar(10))
AS
INSERT INTO MyTable(val1, val2, val3)
VALUES(#val1, #val2, #val3)
return

sql query for deleting rows with NOT IN using 2 columns

I have a table with a composite key composed of 2 columns, say Name and ID. I have some service that gets me the keys (name, id combination) of the rows to keep, the rest i need to delete. If it was with only 1 row , I could use
delete from table_name where name not in (list_of_valid_names)
but how do I make the query so that I can say something like
name not in (valid_names) and id not in(valid_ids)
// this wont work since they separately dont identity a unique record or will it?
Use mysql's special "multiple value" in syntax:
delete from table_name
where (name, id) not in (select name, id from some_table where some_condition);
If your list is a literal list, you can still use this approach:
delete from table_name
where (name, id) not in (select 'john', 1 union select 'sally', 2);
Actually, no I retract my comment about needing special juice or being stuck with (AND OR'ing all your options).
Since you have a list of values of what you want to retain, dump that into a temporary table. Then do a delete against the base table for what does not exist in the temporary table (left outer join). I suck at mysql syntax or I'd cobble together your query. Psuedocode is approximate
DELETE
B
FROM
BASE B
LEFT OUTER JOIN
#RETAIN R
ON R.key1 = B.key1
AND R.key2 = B.key
WHERE
R.key1 IS NULL
The NOT EXISTS version:
DELETE
b
FROM
BaseTable b
WHERE
NOT EXISTS
( SELECT
*
FROM
RetainTable r
WHERE
(r.key1, r.key2) = (b.key1, b.key2)
)