I can apply this query only for one table and I want to apply it for 5 tables in a temporary table with making records in alphabetical order. Because it has freezing problem more then 5000 records and the solution is applying the records when it starts "a letter"
and after "b letter" .... to the end "z letter" for example
amanda
anabele
.
.
.
zeplin
zambia
the important thing is first letter should be in an alphabetical order
shortly I want to make a temporary table and applying the query in alphabeticak order on first letter.. How can I make it?
UPDATE
names INNER JOIN
(SELECT n1.id, n1.name, count(n2.id)+1 cnt
FROM names n1 INNER JOIN names n2
ON n1.name=n2.name AND n1.id>n2.id
GROUP BY n1.id, n1.name) s
ON names.id = s.id
SET
names.name = CONCAT(names.name, '.', s.cnt)
If you want to gather data from multiple tables, I would use UNION or - if you do not want/need to filter out duplicates - UNION ALL (which should be a bit faster).
Example:
SELECT col1, col2
FROM table1
UNION ALL
SELECT col3, col4
FROM table2
If your want it sorted, this is the way (if I remember correctly)
SELECT col1 as column1, col2 as column2
FROM table1
UNION ALL
SELECT col3 as column1, col4 as column2
FROM table2
ORDER BY column1
If you are facing performance issues, consider making your temp table an actual table. You can 'clean' it before (re)filling by simply truncating it and then you can use an insert query per table you want to add. No need to sort it since you can just do a SELECT/ORDER BY on your table.
If the above doesn't help you, perhaps you could add an example of what data you start from and the desired result?
Are you looking for something like this?
CREATE TEMPORARY TABLE temp_names LIKE names;
INSERT INTO temp_names
SELECT id, CONCAT(name, COALESCE(CONCAT('.', rnum), '')) name
FROM
(
SELECT id, name, #n := IF(#g = name, COALESCE(#n, 0) + 1, NULL) rnum, #g := name
FROM names
ORDER BY name
) q;
Related
I am looking to run this query on a list of tables.
SELECT Description,Code,count(*) as count
FROM table1
group by Description,code
having count(*) > 1
I will have to run this query on 30+ different tables, I was wondering If I could change the from statement and just list off the table names.
In addition, is there some functionality that will add the name of the table that it came from in a seperate column to distinguish where the results came from?
Thanks in advance
You might use UNION ALL to put it together. Unless you need some dynamic table selection.
SELECT Description,Code,count(*) as count, 'table1' as tableNane
FROM table1
group by Description,code
having count(*) > 1
UNION ALL
SELECT Description,Code,count(*) as count, 'table2' as tableNane
FROM table2
group by Description,code
having count(*) > 1
...
Actualy I like #Shubhradeep Majumdar version. It will generate more concise code.
SELECT Description,Code, Count(Code), tableName FROM (
SELECT Description,Code, 'table1' as tableName
FROM table1
UNION ALL
SELECT Description,Code, 'table2' as tableName
FROM table2
) tables
GROUP BY tableName, Description, Code
HAVING COUNT(Code) > 1
But there might be a little catch to it. It is more elegant code, but it might actually be slower than first version. The problem is that tableName is appended at every record before grouping while in my first version you do that on already processed data.
Carrying over from #Marek's answer, You could first append all the tables to a table with union all.
select *, 'tab1' as tabnm from tab1
union all
select *, 'tab2' as tabnm from tab2
union all
select *, 'tab3' as tabnm from tab3
-- and so on...
And then use your code to process that final table.
will save you a great deal of time.
EDITED with a column specifying the table name
I have an app that reads from multiple mysql tables, but I'd like to put all the data into 1 table. Thing is, these tables have no linking fields... the app just sequentially processes the rows across the 3 tables, with the hope that the correct rows are lined up in each table (i.e. that row1 in table1 is applicable to row1 in table 2 and table3, and so on)
My tables are as follows:
Table1:
Name,Surname,ID,DoB
Table2:
Address,Town,State
Table3:
password
What I want is :
Table4:
Name,Surname,ID,DoB,Address,Town,State,password
I have created Table4 and I'm now trying to insert the values with a select query...
I've tried ...
SELECT
t1.Name,
t1.Surname,
t1.ID,
t1.DoB,
t2.Address,
t2.Town,
t2.State,
t3.password
FROM table1 AS t1,table2 AS t2, table3 AS t3;
...but this gives me duplicate rows cos there is no where clause. And since there's no linking fields, i can't use a JOIN statement, right?
I'm not a very experienced with SQL, so please help!
Well, officialy you're messed up. There is no first or last row in a RDBMS unless you use an ORDER BY clause. That's also what the manual states. If you issue a
SELECT * FROM your_table;
you can not be sure to get the result in the same order the rows were inserted or in the same order every time you issue the statement at all.
In practice on the other hand, most of the time you will get the same result and most of the time even in the same order the rows were inserted.
What you can do, is, to first slap the one who didn't think of putting a column in each table that determines a sort order (in the future use either an auto_increment column or a timestamp column that holds the date and time of insertion or whatever suits your needs) and second, (but really do this only if you have no other choice, as like I said it's unreliable) you can emulate a row number on which you can join.
SELECT * FROM (
SELECT table1.*, #rn1 := #rn1 + 1 as row_number FROM
table1,
(SELECT #rn1 := 0) v
) a
LEFT JOIN (
SELECT table2.*, #rn2 := #rn2 + 1 as row_number FROM
table2,
(SELECT #rn2 := 0) v
) b ON a.row_number = b.row_number
LEFT JOIN (
SELECT table3.*, #rn3 := #rn3 + 1 as row_number FROM
table3,
(SELECT #rn3 := 0) v
) c ON a.row_number = c.row_number
I need to get a subset of one of my tables, and then use these id's in another query, is this possible?
Ideally, I need to use the result of this query:
SELECT id
FROM table
GROUP BY col1, co12
HAVING COUNT(*) > 1
inside this query:
UPDATE table
SET col1 = CONCAT(col1, '_1')
WHERE id IN (ABOVE_QUERY)
I think you are looking for something like this:
UPDATE
table INNER JOIN (SELECT MAX(id) as m_id
FROM table
GROUP BY col1, co12
HAVING COUNT(*) > 1) t1
ON table.id = t1.m_id
SET col1 = CONCAT(col1, '_1')
In MySQL you need to use a JOIN because you aren't allowed to update a table referenced in a subquery. And you probably need to use an aggregated function on the ID returned by your subquery.
Firstly, if it is relevant, I'm using MySQL, though I assume a solution would work across DB products. My problem is thus:
I have a simple table with a single column. There are no constraints on the column. Within this column there is some simple data, e.g.
a
a
b
c
d
d
I need to get the number/count of values that only appear once. From the example above that would be 2 (since only b and c occur once in the column).
Hopefully it's clear I don't want DISTINCT values, but UNIQUE values. I have actually done this before, by creating an additional table with a UNIQUE constraint on the column and simply INSERTing to the new table from the old one, handling the duplicates accordingly.
I was hoping to find a solution that did not require the temporary table, and could somehow just be accomplished with a nifty SELECT.
Assuming your table is called T and your field is called F:
SELECT COUNT(F)
FROM (
SELECT F
FROM T
GROUP BY F
HAVING COUNT(*) = 1
) AS ONLY_ONCE
select count(*) from
(
select
col1, count(*)
from
Table
group by
Col1
Having
Count(Col1) = 1
)
just nest it a little...
select count( cnt ) from
( select count(mycol) cnt from mytab group by mycol )
where cnt = 1
select field1, count(field1) from my_table group by field1 having count(field1) = 1
select count(*) from (select field1, count(field1) from my_table group by field1 having count(field1) = 1)
first one will return the ones that are unique and second one will return the number of unique elements.
Could it be as simple as this:
Select count(*) From MyTable Group By MyColumn Where Count(MyColumn) = 1
This is what I did and it worked:
SELECT name
FROM people JOIN stars ON stars.person_id = people.id
JOIN movies ON movies.id = stars.movie_id
WHERE year = 2004
GROUP BY name, person_id ORDER BY birth;
note: I was working with several tables here.
CS50 Problem Set 7 (pset7) 9.sql fix!!
I have two tables a and b which has a field name in it.
I need to list the data from these two tables. I thought of using union but in the result list data from the first table appears and then followed by the second.
what i want is to order by the field name so the result should be a mixed up of two tables in the order of name that is order by name.
select slug, name, 1 as mt
from tablea
union
select slug, name, 0 as mt
from tableb
order
by name;
The above is working well for me. will there be any complications in the result of this?
Suppose your query is
SELECT field1 FROM TABLE1 WHERE 1
UNION SELECT field1 FROM TABLE2 WHERE 1
u can make it a subquery like this
SELECT * FROM (SELECT field1 FROM TABLE1 WHERE 1
UNION SELECT field1 FROM TABLE2 WHERE 1) AS `result` ORDER BY `result`.`field1`
Or, you could use a Join query such as:
SELECT tablea.firstname, tablea.middlename, tablea.lastname, tableb.phone
FROM tablea, tableb
WHERE tablea.ID = tableb.ID
Then, you could sort the result however you like.