Can I use column labels in SELECT list as columns? - sql

Let's say I have a table like this:
id | name |
1 | Can add permission |
Can I somehow refer to already defined column labels in select list?
To write something like this:
select id as A, A > 1 as B from auth_permission LIMIT 1;
Looks like not.
But maybe someone knows some cleaver trick? I use PostgreSQL, just in case.

SELECT a,
a > 1 AS b
FROM (SELECT id AS a
FROM auth_permission
LIMIT 1) subsel

Related

Replace the output row text with another text without updating or inserting

I have a query that looks like this:
SELECT
x.ans,
COUNT(*) AS num_ans
FROM
ans x,
get_fit('5')
GROUP BY
x.ans,
get_fit.getfit
ORDER BY
x.ans ASC;
output:
id | num_ans
----+---------------
X | 5
Z | 7
But I want to change the X and Z with AName and BName respectively without inserting or updating the tables. How do i do it?
One option to achieve this, would be CASE command. Your query could look as follows:
SELECT
x.ans as original_id,
CASE WHEN x.ans='X' THEN 'AName'
WHEN x.ans='Z' THEN 'BName'
ELSE x.ans
END as modified_id,
COUNT(*) AS num_ans
FROM
ans x,
get_fit('5')
GROUP BY
x.ans, get_fit.getfit
ORDER BY
x.ans ASC;

SQL find similar content

I have table ITEMS and column URL. All I need is in items.url to find similar rows:
Example of two similar rows:
ITEM_ID | URL
1 | www.google.com/test1/test2/test3.php
2 | www.yahoo.com/test1/test2/test3.php
3 | www.google.com/test5.php
4 | www.facebook.com/test5.php
As you can see the URL is similar JUST with different domains.
My query should be something like:
SELECT * FROM ITEMS
WHERE URL LIKE `%google.com%`...
AND `here code probably` ???
My query should return me ITEM_ID 2 and 4
You could group by the substring starting from the '/' character, and take the max ID in the group. Using postgresql syntax, it should look like this:
SELECT *
FROM ITEMS t
WHERE t.item_id IN (SELECT MAX(s.item_d)
FROM ITEMS s
GROUP BY SUBSTRING(s.url FROM POSITION('/' IN s.url)))
ORDER BY t.item_id;
Update: if you want only google domains, which have similar rows on different domains, you could use a filter EXISTS:
SELECT *
FROM ITEMS t
WHERE t.url LIKE 'www.google.com%'
AND EXISTS (SELECT 1
FROM ITEMS s
WHERE s.url NOT LIKE 'www.google.com%'
AND SUBSTRING(t.url FROM POSITION('/' IN t.url)) =
SUBSTRING(s.url FROM POSITION('/' IN s.url)));

SQL query for two values of one row based off same table column

I have two columns of one row of a report that I would like to be based off the same one column in a SQL table.
For example, in the report it should be something like:
ID | Reason | SubReason
1 | Did not like | Appearance
In the SQL table it is something like:
ID | ReturnReason
1 | Did not like
1 | XX*SR*Appearance
1 | XX - TestData
1 | XX - TestData2
The SubReason column is being newly added and the current SQL query is something like:
SELECT ID, ReturnReason AS 'Reason'
FROM table
WHERE LEFT(ReturnReason,2) NOT IN ('XX')
And now I'd like to add a column in the SELECT statement for SubReason, which should be the value if *SR* is in the value. This however won't work because it also has 'XX' in the value, which is omitted by the current WHERE clause.
SELECT t.ID, t.ReturnReason AS 'Reason',
SUBSTRING(t1.ReturnReason,7,10000) as 'SubReason '
FROM t
LEFT JOIN t as t1 on t.id=t1.id and t1.ReturnReason LIKE 'XX*SR*%'
WHERE t.ReturnReason NOT LIKE 'XX%'
SQLFiddle demo

how to select one tuple in rows based on variable field value

I'm quite new into SQL and I'd like to make a SELECT statement to retrieve only the first row of a set base on a column value. I'll try to make it clearer with a table example.
Here is my table data :
chip_id | sample_id
-------------------
1 | 45
1 | 55
1 | 5986
2 | 453
2 | 12
3 | 4567
3 | 9
I'd like to have a SELECT statement that fetch the first line with chip_id=1,2,3
Like this :
chip_id | sample_id
-------------------
1 | 45 or 55 or whatever
2 | 12 or 453 ...
3 | 9 or ...
How can I do this?
Thanks
i'd probably:
set a variable =0
order your table by chip_id
read the table in row by row
if table[row]>variable, store the table[row] in a result array,increment variable
loop till done
return your result array
though depending on your DB,query and versions you'll probably get unpredictable/unreliable returns.
You can get one value using row_number():
select chip_id, sample_id
from (select chip_id, sample_id,
row_number() over (partition by chip_id order by rand()) as seqnum
) t
where seqnum = 1
This returns a random value. In SQL, tables are inherently unordered, so there is no concept of "first". You need an auto incrementing id or creation date or some way of defining "first" to get the "first".
If you have such a column, then replace rand() with the column.
Provided I understood your output, if you are using PostGreSQL 9, you can use this:
SELECT chip_id ,
string_agg(sample_id, ' or ')
FROM your_table
GROUP BY chip_id
You need to group your data with a GROUP BY query.
When you group, generally you want the max, the min, or some other values to represent your group. You can do sums, count, all kind of group operations.
For your example, you don't seem to want a specific group operation, so the query could be as simple as this one :
SELECT chip_id, MAX(sample_id)
FROM table
GROUP BY chip_id
This way you are retrieving the maximum sample_id for each of the chip_id.

Postgres: regex and nested queries something like Unix pipes

Command should do: Give 1 as output if the pattern "*#he.com" is on the row excluding the headings:
user_id | username | email | passhash_md5 | logged_in | has_been_sent_a_moderator_message | was_last_checked_by_moderator_at_time | a_moderator
---------+----------+-----------+----------------------------------+-----------+-----------------------------------+---------------------------------------+-------------
9 | he | he#he.com | 6f96cfdfe5ccc627cadf24b41725caa4 | 0 | 1 | 2009-08-23 19:16:46.316272 |
In short, I want to connect many SELECT-commands with Regex, rather like Unix pipes. The output above is from a SELECT-command. A new SELECT-command with matching the pattern should give me 1.
Related
Did you mean
SELECT regexp_matches( (SELECT whatevername FROM users WHERE username='masi'), 'masi');
you obviously can not feed the record (*) to regexp_matches, but I assume this is not what your problem is, since you mention the issue of nesting SQL queries in the subject.
Maybe you meant something like
SELECT regexp_matches( wn, 'masi' ) FROM (SELECT whatevername AS wn FROM users WHERE username LIKE '%masi%') AS sq;
for the case when your subquery yields multiple results.
It looks like you could use a regular expression query to match on the email address:
select * from table where email ~ '.*#he.com';
To return 1 from this query if there is a match:
select distinct 1 from table where email ~ '.*#he.com';
This will return a single row containing a column with 1 if there is a match, otherwise no rows at all. There are many other possible ways to construct such a query.
Let's say that your original query is:
select * from users where is_active = true;
And that you really want to match in any column (which is bad idea for a lot of reasons), and you want just to check if "*#he.com" matches any row (by the way - this is not correct regexp! correct would be .*#he.com, but since there are no anchors (^ or $) you can just write #he.com.
select 1 from (
select * from users where is_active = true
) as x
where textin(record_out( x )) ~ '#he.com'
limit 1;
of course you can also select all columns:
select * from (
select * from users where is_active = true
) as x
where textin(record_out( x )) ~ '#he.com'
limit 1;