Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. Database & SysAdmin
  3. Database
  4. Having a bad SQL day

Having a bad SQL day

Scheduled Pinned Locked Moved Database
databasecomhelpquestionannouncement
10 Posts 5 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    TheComputerMan
    wrote on last edited by
    #1

    I am sure I am overlooking something very simple but I can't see it. I have a database of locations with latitudes and longitudes. I need to be able to query for locations that fall within a given radius from a lat/lon point The code I am intending to use is: (Showing fixed centre 38,-118 in this version)

    SELECT quakeid, (6371 * acos(cos(radians(38)) * cos(radians(latitude)) * cos(radians(longitude) - radians(-118)) + sin(radians(38)) * sin(radians(latitude)))) AS [dkm]
    FROM tblUSGSData

    (Derived from Creating a store locator[^]) This works fine and returns just over half a million entries. My problem is that as soon as I add

    HAVING [dkm] <= 50

    or

    WHERE [dkm] <= 50

    I get the message Msg 207, Level 16, State 1, Line 3 Invalid column name 'dkm'. I obviously have not got my SQL glasses on today as I can't seem to resolve this. Can any one make (polite) suggestions?

    J L 2 Replies Last reply
    0
    • T TheComputerMan

      I am sure I am overlooking something very simple but I can't see it. I have a database of locations with latitudes and longitudes. I need to be able to query for locations that fall within a given radius from a lat/lon point The code I am intending to use is: (Showing fixed centre 38,-118 in this version)

      SELECT quakeid, (6371 * acos(cos(radians(38)) * cos(radians(latitude)) * cos(radians(longitude) - radians(-118)) + sin(radians(38)) * sin(radians(latitude)))) AS [dkm]
      FROM tblUSGSData

      (Derived from Creating a store locator[^]) This works fine and returns just over half a million entries. My problem is that as soon as I add

      HAVING [dkm] <= 50

      or

      WHERE [dkm] <= 50

      I get the message Msg 207, Level 16, State 1, Line 3 Invalid column name 'dkm'. I obviously have not got my SQL glasses on today as I can't seem to resolve this. Can any one make (polite) suggestions?

      J Offline
      J Offline
      Jorgen Andersson
      wrote on last edited by
      #2

      Well, [dkm] is an Alias, not a columnname. You would need to have the same expression in the having or where clause as you have in the select clause.

      "The ones who care enough to do it right care too much to compromise." Matthew Faithfull

      T 1 Reply Last reply
      0
      • J Jorgen Andersson

        Well, [dkm] is an Alias, not a columnname. You would need to have the same expression in the having or where clause as you have in the select clause.

        "The ones who care enough to do it right care too much to compromise." Matthew Faithfull

        T Offline
        T Offline
        TheComputerMan
        wrote on last edited by
        #3

        Ah yes. My bad

        SELECT quakeid, latitude, longitude, (6371 * acos(cos(radians(37)) * cos(radians(latitude)) * cos(radians(longitude) - radians(-122)) + sin(radians(37)) * sin(radians(latitude))))
        FROM tblUSGSData
        GROUP BY quakeid, latitude, longitude
        HAVING (6371 * acos(cos(radians(37)) * cos(radians(latitude)) * cos(radians(longitude) - radians(-122)) + sin(radians(37)) * sin(radians(latitude)))) <= 50

        works - at least does not produce an error. Not sure about the working bit but that is another story. Many thanks.

        J B 2 Replies Last reply
        0
        • T TheComputerMan

          Ah yes. My bad

          SELECT quakeid, latitude, longitude, (6371 * acos(cos(radians(37)) * cos(radians(latitude)) * cos(radians(longitude) - radians(-122)) + sin(radians(37)) * sin(radians(latitude))))
          FROM tblUSGSData
          GROUP BY quakeid, latitude, longitude
          HAVING (6371 * acos(cos(radians(37)) * cos(radians(latitude)) * cos(radians(longitude) - radians(-122)) + sin(radians(37)) * sin(radians(latitude)))) <= 50

          works - at least does not produce an error. Not sure about the working bit but that is another story. Many thanks.

          J Offline
          J Offline
          Jorgen Andersson
          wrote on last edited by
          #4

          Are you sure you need to use Haversines formula? If you Radiuses are small enough the Cartesian distance formula would do, depending on what coordinate system you're using of course. Ignore that question, I just remembered what USGS is, and realized it's a different sort of Quake you're working with. :doh:

          "The ones who care enough to do it right care too much to compromise." Matthew Faithfull

          1 Reply Last reply
          0
          • T TheComputerMan

            I am sure I am overlooking something very simple but I can't see it. I have a database of locations with latitudes and longitudes. I need to be able to query for locations that fall within a given radius from a lat/lon point The code I am intending to use is: (Showing fixed centre 38,-118 in this version)

            SELECT quakeid, (6371 * acos(cos(radians(38)) * cos(radians(latitude)) * cos(radians(longitude) - radians(-118)) + sin(radians(38)) * sin(radians(latitude)))) AS [dkm]
            FROM tblUSGSData

            (Derived from Creating a store locator[^]) This works fine and returns just over half a million entries. My problem is that as soon as I add

            HAVING [dkm] <= 50

            or

            WHERE [dkm] <= 50

            I get the message Msg 207, Level 16, State 1, Line 3 Invalid column name 'dkm'. I obviously have not got my SQL glasses on today as I can't seem to resolve this. Can any one make (polite) suggestions?

            L Offline
            L Offline
            Lost User
            wrote on last edited by
            #5

            To add to Jorgen's answer, I've always wondered why SQL Server doesn't allow us to use alias in WHERE and HAVING clauses. The answer to that lies in the logical order in which the query is processed. The WHERE and HAVING clauses are processed before the SELECT clause and the alias do not exist at that stage. However, technically it should be possible to introduce another stage earlier in the query processing pipeline where a mapping between expressions and their alias is made and WHERE and HAVING clauses can look up to these mappings and substitute the actual expression in place of the alias.

            J 1 Reply Last reply
            0
            • L Lost User

              To add to Jorgen's answer, I've always wondered why SQL Server doesn't allow us to use alias in WHERE and HAVING clauses. The answer to that lies in the logical order in which the query is processed. The WHERE and HAVING clauses are processed before the SELECT clause and the alias do not exist at that stage. However, technically it should be possible to introduce another stage earlier in the query processing pipeline where a mapping between expressions and their alias is made and WHERE and HAVING clauses can look up to these mappings and substitute the actual expression in place of the alias.

              J Offline
              J Offline
              Jorgen Andersson
              wrote on last edited by
              #6

              You are looking for CTE.

              "The ones who care enough to do it right care too much to compromise." Matthew Faithfull

              P 1 Reply Last reply
              0
              • T TheComputerMan

                Ah yes. My bad

                SELECT quakeid, latitude, longitude, (6371 * acos(cos(radians(37)) * cos(radians(latitude)) * cos(radians(longitude) - radians(-122)) + sin(radians(37)) * sin(radians(latitude))))
                FROM tblUSGSData
                GROUP BY quakeid, latitude, longitude
                HAVING (6371 * acos(cos(radians(37)) * cos(radians(latitude)) * cos(radians(longitude) - radians(-122)) + sin(radians(37)) * sin(radians(latitude)))) <= 50

                works - at least does not produce an error. Not sure about the working bit but that is another story. Many thanks.

                B Offline
                B Offline
                Bernhard Hiller
                wrote on last edited by
                #7

                By the way, 50 km is about half a degree. Depending on the amount of rows in your table, it might be wise to filter for longitude between -122.5 and -121.5 and latitude between 36.5 and 37.5 first. Also a simple transformation with 110 km/degree for latitude, and 110 * cos(latitude) for longitude, and then using simple pythagoras might speed up the query.

                T 1 Reply Last reply
                0
                • B Bernhard Hiller

                  By the way, 50 km is about half a degree. Depending on the amount of rows in your table, it might be wise to filter for longitude between -122.5 and -121.5 and latitude between 36.5 and 37.5 first. Also a simple transformation with 110 km/degree for latitude, and 110 * cos(latitude) for longitude, and then using simple pythagoras might speed up the query.

                  T Offline
                  T Offline
                  TheComputerMan
                  wrote on last edited by
                  #8

                  Thanks for your input. Yes I am adding some filtering now. I just needed to get the thing working first.

                  1 Reply Last reply
                  0
                  • J Jorgen Andersson

                    You are looking for CTE.

                    "The ones who care enough to do it right care too much to compromise." Matthew Faithfull

                    P Offline
                    P Offline
                    PIEBALDconsult
                    wrote on last edited by
                    #9

                    Yes, or a simple

                    SELECT ... FROM
                    (
                    SELECT ... FROM table WHERE ...
                    ) T
                    ...

                    J 1 Reply Last reply
                    0
                    • P PIEBALDconsult

                      Yes, or a simple

                      SELECT ... FROM
                      (
                      SELECT ... FROM table WHERE ...
                      ) T
                      ...

                      J Offline
                      J Offline
                      Jorgen Andersson
                      wrote on last edited by
                      #10

                      Yes, thats equivalent. I just prefer the readability of the CTE (which is merely an opinion) plus that you can refer to a CTE in more than one place.

                      "The ones who care enough to do it right care too much to compromise." Matthew Faithfull

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups