MySQL - Select two columns as one based on condition - mysql

In the table above there is a column called from_stop and a column called to_stop.
I want to select all from_stop values where from_timing is equal to 'PTP' and select all to_stop values where to_timing is equal to 'PTP', in a single column.
So essentially I should have a column called stop that selects what I've said above.
I have made a few attempts but this query is baffling me because of poor relational set up, I am aware of that but this can't be changed.
Any ideas?
Example results:
stop_column
1900HA030090
1900HA058450
So essentially I have a column of results where the from_timing and from_stop are equal or to_timing and to_stop are equal.

SELECT from_stop FROM <rel_name> WHERE from_timing = 'PTP'
UNION
SELECT to_stop FROM <rel_name> WHERE to_timing = 'PTP'
This will remove all duplicates, if you want to retain duplicates use UNION ALL instead

Related

Why does SELECT COUNT(*) return 1 when no table is selected? [duplicate]

could you please explain why mysql count function without providing any table name gives 1 as value?
SELECT COUNT(*);
Result: 1
Because in mysql select constant_value command is valid (such as select 2 will return 2) and will return 1 row. Count() function without group by will collapse the resultset and count the number of items in the resultset. In this case 1 row would be returned and count(*) counts that.
Normally all selects are of the form SELECT [columns, scalar computations on columns, grouped computations on columns, or scalar computations] FROM [table or joins of tables, etc]
Because this allows plain scalar computations we can do something like SELECT 1 + 1 FROM SomeTable and it will return a recordset with the value 2 for every row in the table SomeTable.
Now, if we didn't care about any table, but just wanted to do our scalar computed we might want to do something like SELECT 1 + 1. This isn't allowed by the standard, but it is useful and most databases allow it (Oracle doesn't unless it's changed recently, at least it used to not).
Hence such bare SELECTs are treated as if they had a from clause which specified a table with one row and no column (impossible of course, but it does the trick). Hence SELECT 1 + 1 becomes SELECT 1 + 1 FROM ImaginaryTableWithOneRow which returns a single row with a single column with the value 2.
Mostly we don't think about this, we just get used to the fact that bare SELECTs give results and don't even think about the fact that there must be some one-row thing selected to return one row.
In doing SELECT COUNT() you did the equivalent of SELECT COUNT() FROM ImaginaryTableWithOneRow which of course returns 1.
Reference

combine duplicate records rows in sql into one row

I have duplicate records in one sql table . The rows has the same id but different values in different fields. how I can combine or merge those two rows or more into one row. Please help,
You can group those rows on certain fields by specifying a GROUP BY clause.
In your case you would group on the ID column. For the columns you select in the SELECT clause that are not specified in the GROUP BY clause (i.e. columns other than ID), you will have to apply an aggregate function (e.g. SUM, MAX, MIN, ...).
Edit - Simplified example based on your image:
SELECT
MasterID,
CUSTNAME=MIN(CUSTNAME),
ER1=MIN(ER1),
ER1_BU=MIN(ER1_BU)
-- For the other fields, the idea is the same
FROM
your_table
GROUP BY
MasterID
ORDER BY
MasterID;
This example takes for each field the minimum of the fields for a particular MasterID. You did not really define what you mean by "merge". Perhaps you want the result to be a particular merge, you will have to clarify further if this example doesn't "merge" the rows like you want.

SQL statement for displaying unique values

Below is the data in my table:
TABLE:
abc-ac
abc-dc
aax-i
bcs-o-dc
ddd-o-poe-dc
I need to write a query which will display only the unique entries as a result:
abc-ac
aax-i
bcs-o-dc
ddd-o-poe-dc
So basically, since the first two entries start with "abc", it should be treated as one and displayed.
Thanks.
If you're not picky about which one of the two abc-* records that it shows you can use this:
SELECT f1 FROM mytable GROUP BY substring_index(f1, '-', 1)
SQLFiddle Here
That substring_index() function will split the value in your field by - and return the first bit. So essentially your records get grouped by only the first part. This is one of the few times that we can take advantage of MySQLs strange GROUP BY behavior where it will allow you to leave out non-aggregated fields from the group by.

MySQL Get list with values from two columns

Say I have this table with two columns. Both columns contain IP-addresses. I want a SELECTquery that gets me a list of all ip-addresses that occur in either the first column, or the second column, or both. Just a list of all distinct ip-addresses in that table. How is that done? I would have thought that SELECT DISTINCT ip_src, ip_dst FROM table would have done the trick.
Note that your example only applies the distinct to ip_src. To get just one column try a UNION:
SELECT ip_src FROM table
UNION
SELECT ip_dst FROM table
As noted in the comments not only will the UNION remove duplicates between the columns but also those that occur with the columns meaning using a DISTINCT is unnecessary.

How do I use distinct for a column along with a where clause in sql server 2008?

I want to get the distinct value of a particular column however duplicity is not properly managed if more than 3 columns are selected.
The query is:
SELECT DISTINCT
ShoppingSessionId, userid
FROM
dbo.tbl_ShoppingCart
GROUP BY
ShoppingSessionId, userid
HAVING
userid = 7
This query produces correct result, but if we add another column then result is wrong.
Please help me as I want to use the ShoppingSessionId as a distinct, except when I want to use all the columns from the table, including with the where clause .
How can I do that?
The DISTINCT keyword applies to the entire row, never to a column.
Presently DISTINCT is not needed at all, because your script already makes sure that ShoppingSession is distinct: by specifying the column in GROUP BY and filtering on the other grouping column (userid).
When you add a third column to GROUP BY and it results in duplicated ShoppingSession, it means that some ShoppingSession values are associated with many different values of the added column.
If you want ShoppingSession to remain distinct after including that third column, you should decide which values of the the added column should be left in the output and which should be discarded. This is called aggregating. You could apply the MAX() function to that column, or MIN() or any other suitable aggregate function. Note that the column should not be included in GROUP BY in this case.
Here's an illustration of what I'm talking about:
SELECT
ShoppingSessionId,
userid,
MAX(YourThirdColumn) AS YourThirdColumn
FROM dbo.tbl_ShoppingCart
GROUP BY
ShoppingSessionId,
userid
HAVING userid = 7
There's one more note on your query. The HAVING clause is typically used for filtering on aggregated columns. If your filter does not involve aggregated columns, you'll be better off using the WHERE clause instead:
SELECT
ShoppingSessionId,
userid,
MAX(YourThirdColumn) AS YourThirdColumn
FROM dbo.tbl_ShoppingCart
WHERE userid = 7
GROUP BY
ShoppingSessionId,
userid
Although both queries would produce identical results, their efficiency would be different, because the first query would have to pull all rows, group/aggregate them, then discard all rows except userid = 7, but the second one would discard rows first and only then group/aggregate the remaining, which is much more efficient.
You could go even further and exclude the userid column from GROUP BY and pull its value with an aggregate function:
SELECT
ShoppingSessionId,
MAX(userid) AS userid,
MAX(YourThirdColumn) AS YourThirdColumn
FROM dbo.tbl_ShoppingCart
WHERE userid = 7
GROUP BY
ShoppingSessionId
Since all userid values in your output are supposed to contain 7 (because that's in your filter), you can just pick a maximum value per every ShoppingSession, knowing that it'll always be 7.