This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
SQL exclude a column using SELECT * [except columnA] FROM tableA?
Is selecting all columns except one column possible??
here is all column names: id, name, address, age
SELECT id, name, address from TBLUser
I don't want to use this select statement because the number of columns of my tables are different to each other.
declare #cols varchar(max), #sql varchar(max)
SELECT #cols = STUFF
(
(
SELECT DISTINCT '], [' + name
FROM sys.columns
where object_id = (
select top 1 object_id from sys.objects
where name = 'TBLUser'
)
and name not in ('age')
FOR XML PATH('')
), 1, 2, ''
) + ']'
select #sql = 'select ' + #cols + ' from TBLUser'
exec (#sql)
How about:
SELECT * FROM sys.columns
WHERE Name <> N'Column To Exclude' and Object_ID = Object_ID(N'TBLUser')
This will return all columns except the one you wish to exclude.
Expanded explanation:
According to this explanation from SQL Cheat Sheet
sys.columns is a system table and is used for maintaining information on columns in a database. For every column added in database, a record is created in the sys.columns table. There is only one record for each column
Name: The name of the column. This is unique within the table object.
Object_id:object_id is unique identifier for table in which the column exists. We will use this column to join sys.columns with sys.tables in order to fetch columns in different tables.
We are selecting all results from sys.columns where the name is not equal to whatever you provide, replace 'Column To Exclude' with your column name. We are also requiring that the object_id equal the object_id you provide. object_id is a number that represents the table you want to filter out the one column from. In this ops case the table was TBLUser, in other uses it would be like this object_id(N'[dbo].[YourTable]'), you would replace [YourTable] with your own table name
in sql*plus,
the one way is to disable as follows:
sql> column age noprint
sql> SELECT * from TBLUser
then, you can revert using
sql>column age off
or else you've to user dynamically with DBMS_SQL package.
Related
Let us say I have two tables with many columns so I do not want to name the column names explicitly in my query but i want to avoid duplicate names.
If I do:
CREATE TABLE new_table
SELECT a.*, b.*
FROM table1 a
INNER JOIN table2 b ON a.myID = b.myId
WHERE a.age > 10 and b.ice = 'melted'
I will get an error saying: duplicate column name myId, I could also get more errors if more column names in a and b are the same.
How can I avoid this issue by automatically adding a prefix to all column names in a.* and b.* w/o explicitly mentioning all the column names - very tedious to do so!
Thanks!
Unfortunately, you will have to list the columns in case table have matching column names. However, you can use information_schema to get the column names, format those and copy paste in the query to save the pain, e.g.:
SELECT GROUP_CONCAT(CONCAT('a.', COLUMN_NAME)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'schema' AND TABLE_NAME = 'table';
The above query should give you comma separated column names with a. prefix. You can then use the same query for table b, get the names out and use it in the main SELECT query.
Update
As #Uueerdo has rightly said, you can add alias to columns as well, e.g.:
SELECT GROUP_CONCAT(CONCAT('a.', COLUMN_NAME, ' AS a_', COLUMN_NAME))
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'schema' AND TABLE_NAME = 'table';
In my experience ORMs will run an initial DESCRIBE query so it can do this sort of stuff for you once it has the column names. But if you insist on doing it dynamically in a single query, you could do this with pure MySQL:
-- config
SET #database = 'your_database';
SET #tableA = 'table1';
SET #tableB = 'table2';
-- table alias "a" columns
SET #fieldsA = NULL;
SELECT GROUP_CONCAT(CONCAT('a.', COLUMN_NAME), ' AS ',CONCAT('`a.', COLUMN_NAME,'`')) INTO #fieldsA
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = #database AND TABLE_NAME = #tableA;
-- table alias "b" columns
SET #fieldsB = NULL;
SELECT GROUP_CONCAT(CONCAT('b.', COLUMN_NAME), ' AS ',CONCAT('`b.', COLUMN_NAME,'`')) INTO #fieldsB
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = #database AND TABLE_NAME = #tableB;
-- some variables for readability
SET #fields = CONCAT(' ', #fieldsA, ',', #fieldsB,' ');
SET #tableAliasA = CONCAT(' ',#database, '.', #tableA,' a ');
SET #tableAliasB = CONCAT(' ',#database, '.', #tableB,' b ');
-- generate our final query
SET #query = CONCAT('CREATE TABLE new_table SELECT', #fields,
'FROM', #tableAliasA,
'INNER JOIN', #tableAliasB,
'ON a.myID = b.myId WHERE a.age > 10 and b.ice = ''melted''');
-- finally run the query:
PREPARE stmt1 FROM #query;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
-- if you have problems with the above query, uncomment the following to get the query so you can run it separately
-- SELECT #query;
I'd strongly advise against using this sort of solution though. I'd sooner run an initial DESCRIBE query as earlier stated, then generate your query based on that. Another solution is to create a temporary table as a copy of the second table, then rename problematic columns, then proceed to join on it to produce the data you need to create your new_table. MySQL has no issues with result columns having the same name, the issue here is trying to create a table with two columns with the same name. So essentially what you're trying to do is a star select but excluding a column.
Another approach is to just select only the primary key from both:
SELECT a.myID as `aId`, b.myId as `bId` then create your table containing only that. Then if you ever need data from a particular table, just LEFT JOIN on it to grab the information you're looking for. You can take this a step further and set up a VIEW to do this sort of thing for you. VIEWs can join tables for you and make it very easy to select whatever columns you're looking for. You can also setup multiple VIEWs as well. Also note that views behave just like tables for the purpose of joins. You can JOIN a view with a table, or you can join a view with a view, etc.
So rather than do what you're trying to do -- creating a new table with the data from two other tables -- consider whether you're actually looking for a VIEW.
I have unique column url varchar(4), and want to update it to unique random string, but having problems with duplicated items.
So I want to create loop something like this, but having problem with targeting twice same table.
UPDATE IGNORE word SET url = (SELECT GROUP_CONCAT(SUBSTRING('1234567890qwertyuiopasdfghjklzxcvbnm' , 1+ FLOOR(RAND()*LENGTH('1234567890qwertyuiopasdfghjklzxcvbnm')) ,1) SEPARATOR '')
FROM (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS dummy_tbl)
WHERE EXISTS (SELECT url FROM word WHERE url IS NULL);
What is the best way to fill my column, with single query?
You should remove the EXISTS clause and just update the NULL rows directly:
UPDATE
IGNORE word
SET url = ...
WHERE url IS NULL;
So your full query would be:
UPDATE
IGNORE word
SET url =
(SELECT GROUP_CONCAT(SUBSTRING('1234567890qwertyuiopasdfghjklzxcvbnm',
1+ FLOOR(RAND()*LENGTH('1234567890qwertyuiopasdfghjklzxcvbnm')),1) SEPARATOR '')
FROM
(SELECT 1
UNION SELECT 2
UNION SELECT 3
UNION SELECT 4) AS dummy_tbl)
WHERE url IS NULL;
If SQL query contains all fields what I need it will be very large.
How in SQL query I can select field from F3 to F 100 and from F150 to F200?
SELECT F3 to F100, F150 to F200 FROM database;
It is possible or not???
Tables structure change is not available
You have to :
1- manually select all columns . Or
2- do
Select * from database
And then just fetch the columns you need.
There are no shortcuts for this, you will have to list the fields needed one way or another. If the fields being selected are always the same, you should create a view for that as:
CREATE VIEW SomeView AS
SELECT
F3,
...
F100
FROM
SomeTable
and then select like:
SELECT * FROM SomeView
But again, you will have to list the fields at least once.
SELECT F3 to F100, F150 to F200 FROM database;
this query can not possible..
you must have to specify all the columns name
like select F1,f2,f3 from database;
You can't.
But if it's not possible to modify your table structure to fix the database design issue, you can use an SQL query to generate the MySQL query:
SELECT CONCAT('SELECT ', GROUP_CONCAT(COLUMN_NAME), ' FROM `your table`')
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = 'your schema' and TABLE_NAME = 'your table'
GROUP BY TABLE_NAME
Add a filter in WHERE to select only the desired fields.
I need to create unique SEO words for website by adding - to distinct words.
I tried query
UPDATE url_alias SET `keyword = (SELECT DISTINCT CONCAT( keyword, '-' ));
but this query adds - to all words. What is wrong with this query?
Example: Words are Acer, Acer, Acer-, Apple, Apple, Apple- and these should be finally Acer, Acer-, Acer--, Apple, Apple-, Apple--
Table example in here.
UPDATE url_alias SET `keyword` = `keyword` + '-'
I need to create unique SEO words for website by adding - to distinct
words. ...
but this query adds - to all words. What is wrong with this query?
You can use a WHERE condition to filter and set values to specific occurrences.
Example:
UPDATE url_alias SET keyword = CONCAT( keyword, '-' )
where keyword = ?
Change the where condition as desired to match an occurrence and execute.
Try this
UPDATE url_alias U1 SET keyword =
(SELECT CONCAT( keyword, '-' ) from url_alias group by keyword) U2
where U2.id=U1.id;
Try with:
CREATE TEMPORARY TABLE TSEL SELECT keyword FROM url_alias GROUP BY keyword HAVING COUNT(keyword) = 1;
UPDATE url_alias SET keyword = CONCAT( keyword, '-' ) WHERE keyword IN (SELECT keyword FROM TSEL);
This is:
Create a temporary table containing all unique keywords: This is, they are not repeated at different rows.
Updating those keywords contained in TSEL.
TSEL will be automatically deleted when your session is finished. Nevertheless you can delete it explicitly using:
DROP TABLE TSEL;
EDIT
If you want to ignore case as well as already inserted '-' characters, you will have to normalize keyword when the time to calculate candidates to update comes. In this case, your new SQLs should be:
CREATE TEMPORARY TABLE TSEL SELECT UCASE(TRIM( BOTH '-' FROM keyword)) AS keyword FROM url_alias GROUP BY UCASE(TRIM( BOTH '-' FROM keyword)) HAVING COUNT(1) = 1;
UPDATE url_alias SET keyword = CONCAT( keyword, '-' ) WHERE UCASE(TRIM( BOTH '-' FROM keyword)) IN (SELECT keyword FROM TSEL);
If you consider "Acer" and "Acer-" as different:
CREATE TABLE TSEL SELECT UCASE(keyword) AS keyword FROM url_alias GROUP BY UCASE(keyword) HAVING COUNT(1) = 1;
UPDATE url_alias SET keyword = CONCAT( keyword, '-' ) WHERE UCASE(keyword) IN (SELECT keyword FROM TSEL);
I have a table which consists of 64 different fields. i am going to search with a single keyword in it, Results should match the keyword from any field. Give some suggestions.
SELECT * FROM `some_table`
WHERE
CONCAT_WS('|',`column1`,`column2`,`column3`,`column4`,`column64`) # single condition, many columns
LIKE '%VT%'
Voila.
The '|' separator, by the way, is to prevent you finding coincidental matches where, e.g., column1 ends in 'V' and column2 starts with 'T', which would give you a false positive in a search for "VT".
I'm not sure if the above method is faster than the OR method (I would guess they're the same speed) , but it definitely involves less typing if you're writing the query by hand.
you can use the where with multiple condition with OR
like
where
name = 'expected'
OR rate ='expected'
OR country ='expected'
I can't see a way around your query being simple but long:
SET #term = "Somesearch";
SELECT id, title FROM sometable WHERE
col1 LIKE '%#term%' OR
col2 LIKE '%#term%' OR
col3 LIKE '%#term%' ...;
Instead of using a MySQL variable, you can just use a language-specific variable but for the sake of examples, I thought I'd stick with MySQL itself.
The "..." is where you'd place the other 61 columns/fields.
Another possibility would be to use FOR XML to get all columns to print to a single field... like this:
SELECT c.*
FROM (
SELECT a.*
,( SELECT *
FROM table_to_search b
WHERE a.KeyField = b.KeyField
FOR XML RAW) AS `Full_Text_Record`
FROM table_to_search a) c
WHERE c.`Full_Text_Record` LIKE '%Search_string%'
Might take a while to run if it is a particularly large table, but it should brute force you to find out if that string exists in any given table.
If you can translate this SQL Server syntax to MySQL
WHERE
name = #keyword OR
country = #keyword OR
department = #keyword OR
#keyword IS NULL -- match all when search text is empty
Simplest solution would be to use multiple ORs.
select * from TAB where col1 like "%VAR%" OR col2 like "%VAR%" OR......col64 like "%VAR%";
You can use like or = as per the requirement, but it will require to change your query every time you add a new column.
As an alternative, you can take SQLDump for that table and then search that file.
With some Googling,
See if this project is useful - http://code.google.com/p/anywhereindb/. Searches all the fields and praised by many.
Try to use the information from information_schema table. Look for all the columns in the table. Now, try to form your query using this information.
You could write one query that will generate a query for every column in your table.
In the example below the schema ("owner") is 'DEV_USER'
The table with your 64 fields is called 'CUSTOMER_INFO'
The criteria in the search is any column with a value of 'VT' in it:
select 'SELECT ' || COLUMN_NAME || ' FROM CUSTOMER_INFO
WHERE ' || COLUMN_NAME || q'# LIKE '%VT%';#'
FROM ALL_TAB_COLS
WHERE OWNER = 'DEV_USER'
AND TABLE_NAME = 'CUSTOMER_INFO';
This one query will generate a query for each field for you.
The results of running the above would be;
SELECT ADDRESS_1 FROM CUSTOMER_INFO
WHERE ADDRESS_1 LIKE '%VT%';
SELECT ADDRESS_2 FROM CUSTOMER_INFO
WHERE ADDRESS_2 LIKE '%VT%';
SELECT CITY FROM CUSTOMER_ADDRESSES_QASB
WHERE CITY LIKE '%VT%';
SELECT STATE_PROVINCE FROM CUSTOMER_INFO
WHERE STATE_PROVINCE LIKE '%VT%';
SELECT ZIP_POSTAL_CODE FROM CUSTOMER_INFO
WHERE ZIP_POSTAL_CODE LIKE '%VT%';
WHERE LATITUDE LIKE '%VT%';
... and so on for each column in the table
Then you just paste those queries that were generated from your first query into another tab and run them.
Hope that helps. :-)
You can use dynamic SQL to generate and execute a query that searches all the columns.
DELIMITER $$
CREATE PROCEDURE searchAllCols(inDB VARCHAR(64), inTable VARCHAR(64), search VARCHAR(32))
BEGIN
SET #matches = (
SELECT GROUP_CONCAT(CONCAT('`', COLUMN_NAME, '` LIKE "%', search, '%"') SEPARATOR ' OR ')
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = inTable and table_schema = inDB);
SET #query = CONCAT('SELECT * FROM `', inDB, '`.`', inTable, '` WHERE ', #matches);
PREPARE stmt FROM #query;
EXECUTE stmt;
END
$$
DELIMITER ;
CALL searchAllCols('table_to_search', 'searchString');