-2

I have two tables, one is an index (or map) which helps when other when pulling queries.

SELECT v.*
FROM smv_ v
WHERE (SELECT p.network
       FROM providers p
       WHERE p.provider_id = v.provider_id) = 'RUU='
AND (SELECT p.va
     FROM providers p
     WHERE p.provider_id = v.provider_id) = 'MjU='
LIMIT 1;

Because we do not know the name of the column that holds the main data, we need to look it up, using the provider_id which is in both tables, and then query.

I am not getting any errors, but also no data back. I have spent the past hour trying to put this on sqlfiddle, but it kept crashing, so I just wanted to check if my code is really wrong, hence the crashing?

In the above example, I am looking in the providers table for column network, where the provider_id matches, and then use that as the column on smv.

I am sure i have done this before just like this, but after the weekend trying I thought i would ask on here.

Thanks in Advance.

UPDATE

Here is an example of the data:

THis is the providers, this links so no matter what the name of the column on the smv table, we can link them.

+---+---+---------------+---------+-------+--------+-----+-------+--------+
|   | A |    B     |    C    |   D   |   E    |  F  |   G   |   H    |
+---+---+---------------+---------+-------+--------+-----+-------+--------+
| 1 | 1 | Home     | network | batch | bs     | bp  | va    | bex    |
| 2 | 2 | Recharge | code    | id    | serial | pin | value | expire |
+---+---+---------------+---------+-------+--------+-----+-------+--------+

In the example above, G will mean in the smv column for recharge we be value. So that is what we would look for in our WHERE clause.

Here is the smv table:

+---+---+-----------+-----------+---+----+---------------------+-----+--+
|   | A |  B |     C    | D | E  |          F          |  value  | va |
+---+---+-----------+-----------+---+----+---------------------+-----+--+
| 1 | 1 | X2 | Home     | 4 | 10 | 2016-09-26 15:20:58 |         | 7 |
| 2 | 2 | X2 | Recharge | 4 | 11 | 2016-09-26 15:20:58 |  9      |   |
+---+---+-----------+-----------+---+----+---------------------+-----+--+

value in the same example as above would be 9, or 'RUU=' decoded.

So we do not know the name of the rows, until the row from smv is called, once we have this, we can look up what column name we need to get the correct information.

Hope this helps.

MORE INFO

At the point of triggering, we do not know what the row consists of the right data because some many of the fields would be empty. The map is there to help we query the right column, to get the right row (smv grows over time depending on whats uploaded.)

1) SELECT p.va FROM providers p WHERE p.network = 'Recharge' ;
2) SELECT s.* FROM smv s, providers p WHERE p.network = 'Recharge'; 

1) gives me the correct column I need to look up and query smv, using the above examples it would come back with "value". So I need to now look up, within the smv table, C = Recharge, and value = '9'. This should bring me back row 2 of the smv table.

So individually both 1 and 2 queries work, but I need them put together so the query is done on the database server.

Hope this gives more insight

Even More Info

From reading other posts, which are not really doing what I need, i have come up with this:

SELECT s.*
FROM (SELECT
        (SELECT p.va
         FROM dh_smv_providers p
         WHERE p.provider_name = 'vodaphone'
         LIMIT 1) AS net,
        (SELECT p.bex
         FROM dh_smv_providers p
         WHERE p.provider_name = 'vodaphone'
         LIMIT 1) AS bex
      FROM dh_smv_providers) AS val, dh_smv_ s
WHERE s.provider_id = 'vodaphone' AND net = '20'
ORDER BY from_base64(val.bex) DESC;

The above comes back blank, but if i replace net, in the WHERE clause with a column I know exists, I do get the results expected:

SELECT s.*
FROM (SELECT
        (SELECT p.va
         FROM dh_smv_providers p
         WHERE p.provider_name = 'vodaphone'
         LIMIT 1) AS net,
        (SELECT p.bex
         FROM dh_smv_providers p
         WHERE p.provider_name = 'vodaphone'
         LIMIT 1) AS bex
      FROM dh_smv_providers) AS val, dh_smv_ s
WHERE s.provider_id = 'vodaphone' AND value = '20'
ORDER BY from_base64(val.bex) DESC;

So what I am doing wrong, which is net, not showing the value derived from the subquery "value" ?

Thanks

BadAddy
  • 346
  • 1
  • 4
  • 12
  • 1
    I think `select`s within selects are executed first, so your first inner select will not know what `v.provider_id` is as it's not referenced within the inner select. The same issue applies to the second inner select as well. – Martin Sep 26 '16 at 14:37
  • So if i reverse it, it should work ? – BadAddy Sep 26 '16 at 16:33
  • Maybe, the order in which MySQL processes subqueries is the inner queries are executed without any knowledge of values from the outer query. So you need to insert the value of `v` into the inner query. By the looks of your SQL you should be using `JOIN`s. – Martin Sep 26 '16 at 17:17
  • I really do dislike it when people mark down others, but do not explain the reasons! – BadAddy Sep 26 '16 at 18:43
  • I'm sorry but the more I look at this the more it looks like this method is a massive limiter on the usefulness of the database. Have you read up about [many-to-many](http://www.phpknowhow.com/mysql/many-to-many-relationships/) SQL relationships? It looks like you're sort of needing that approach, whereas instead of G or F you have a column name `COL` (example only) and in COL you have the row of another table such as `COL_name` and for that row of `col_name` you have a value that is `va` or `value`, etc. I know I'm explaining this bady but I think it would be easier for you – Martin Sep 26 '16 at 20:14
  • ...to research using an alternative SQL structure to the one you've currently got set up. [reference one](http://www.joinfu.com/2005/12/managing-many-to-many-relationships-in-mysql-part-1/) and [reference two](http://stackoverflow.com/questions/2923809/many-to-many-relationships-examples) should both be helpful. You need to generate youself a key-mapping table which will contain the column names and be easy to `JOIN` to your data column(s). – Martin Sep 26 '16 at 20:16
  • as a matter of policy I always down votes questions where columns as A,B,D .... – e4c5 Sep 27 '16 at 01:58
  • @e4c5 I find that a silly policy, especially as I have already said the column names are mostly unknown! But thank you for posting the reason. – BadAddy Sep 27 '16 at 06:59
  • @Martin Thank you, but it seems it will not work using many to many. The issue I have is using the result of a subquery as a column name, in a higher query. If I join tables, in any fashion, it will not provide me the ability to re-query, without asking another call. ... – BadAddy Sep 27 '16 at 16:16
  • ... if you take the smv example, value, and val are what I need to filter on with the outter query. So they both relate to the same thing, but just named differently, but i will not know if it's 'value', or 'val', until I have first selected the provider_id from smv. So I wanted to do two queries at the same time, or in the same call. If that makes sense ? – BadAddy Sep 27 '16 at 16:18
  • My comments were that I would suggest you stopped naming columns in tables and *instead* use a manyto-many relationship, to avoid these sort of problems. The m-2-m doesnt solve your specific situation but does stop this situation occuring in the future. – Martin Sep 27 '16 at 17:32
  • You can probably find a (bit of a bodgy) workaround for your current predicament using the MySQL `INFORMATION_SCHEMA` table which contains the data of your records table. Have a read up on that topic `:-)` – Martin Sep 27 '16 at 17:32
  • reference link for `information_schema`: http://stackoverflow.com/questions/4165195/mysql-query-to-get-column-names (you'll have to customise this for your situation but this should be a starting point for you ) – Martin Sep 27 '16 at 17:34

1 Answers1

0
SELECT 
    v.*, 
    p.network, p.va
FROM 
    smv_ v 
INNER JOIN 
    providers p ON p.provider_id = v.provider_id
WHERE 
    p.network = 'RUU=' AND p.va = 'MjU='
LIMIT 1;

The tables talk to each other via the JOIN syntax. This completely circumvents the need (and limitations) of sub-selects.

The INNER JOIN means that only fully successful matches are returned, you may need to adjust this type of join for your situation but the SQL will return a row of all v columns where p.va = MjU and p.network = RUU and p.provider_id = v.provider_id.

What I was trying to explain in comments is that subqueries do not have any knowledge of their outer query:

SELECT * 
FROM a 
WHERE (SELECT * FROM b WHERE a) 
  AND (SELECT * FROM c WHERE a OR b)

This layout (as you have in your question) is that b knows nothing about a because the b query is executed first, then the c query, then finally the a query. So your original query is looking for WHERE p.provider_id = v.provider_id but v has not yet been defined so the result is false.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Martin
  • 22,212
  • 11
  • 70
  • 132
  • thank you, I have had a look at what you have said, but I guess why I am trying to achieve I cannot do with just one query. I do not know the name of the column, which is in smv, and I cannot get to the providers with the correct ID, because that is in the smv. I wanted to do this in one query, but it seems I cannot. – BadAddy Sep 26 '16 at 18:46
  • If you can edit your question and show some example data tables so we can get a clear idea of what db structure you have, and then we can try and make you a single SQL query that does what you want. – Martin Sep 26 '16 at 19:11
  • What tool online will do that, because sqlfiddle wasted over an hour this morning ? – BadAddy Sep 26 '16 at 19:31
  • I don't have much experience of SQLFiddle but something like that. I think a [`show create table`](http://stackoverflow.com/a/898709/3536236) output from your SQL table will help too. Obviously trim it down and then [manually] populate it with some data, you can manually write out for example just a couple of the important column rows from each table, we don't need columns that arn't mentioned in the question, and put it in an ***edit*** as some times people try and write code in comments and it's a mess to read and understand. `:-)` – Martin Sep 26 '16 at 20:08
  • @BadAddy oh sorry I've just seen your update, yes that's exactly what I'm after....... – Martin Sep 26 '16 at 20:09