diff --git a/homeassistant/components/sensor/sql.py b/homeassistant/components/sensor/sql.py
new file mode 100644
index 0000000000000000000000000000000000000000..a0648d4851a6876b6e2279d591acd194253049cd
--- /dev/null
+++ b/homeassistant/components/sensor/sql.py
@@ -0,0 +1,145 @@
+"""
+Sensor from an SQL Query.
+
+For more details about this platform, please refer to the documentation at
+https://home-assistant.io/components/sensor.sql/
+"""
+import logging
+
+import voluptuous as vol
+
+from homeassistant.components.sensor import PLATFORM_SCHEMA
+from homeassistant.const import (
+    CONF_NAME, CONF_UNIT_OF_MEASUREMENT, CONF_VALUE_TEMPLATE)
+from homeassistant.components.recorder import (
+    CONF_DB_URL, DEFAULT_URL, DEFAULT_DB_FILE)
+import homeassistant.helpers.config_validation as cv
+from homeassistant.helpers.entity import Entity
+
+_LOGGER = logging.getLogger(__name__)
+
+REQUIREMENTS = ['sqlalchemy==1.2.2']
+
+CONF_QUERIES = 'queries'
+CONF_QUERY = 'query'
+CONF_COLUMN_NAME = 'column'
+
+_QUERY_SCHEME = vol.Schema({
+    vol.Required(CONF_NAME): cv.string,
+    vol.Required(CONF_QUERY): cv.string,
+    vol.Required(CONF_COLUMN_NAME): cv.string,
+    vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string,
+    vol.Optional(CONF_VALUE_TEMPLATE): cv.template,
+})
+
+PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
+    vol.Required(CONF_QUERIES): [_QUERY_SCHEME],
+    vol.Optional(CONF_DB_URL): cv.string,
+})
+
+
+def setup_platform(hass, config, add_devices, discovery_info=None):
+    """Setup the sensor platform."""
+    db_url = config.get(CONF_DB_URL, None)
+    if not db_url:
+        db_url = DEFAULT_URL.format(
+            hass_config_path=hass.config.path(DEFAULT_DB_FILE))
+
+    import sqlalchemy
+    from sqlalchemy.orm import sessionmaker, scoped_session
+
+    try:
+        engine = sqlalchemy.create_engine(db_url)
+        sessionmaker = scoped_session(sessionmaker(bind=engine))
+
+        # run a dummy query just to test the db_url
+        sess = sessionmaker()
+        sess.execute("SELECT 1;")
+
+    except sqlalchemy.exc.SQLAlchemyError as err:
+        _LOGGER.error("Couldn't connect using %s DB_URL: %s", db_url, err)
+        return
+
+    queries = []
+
+    for query in config.get(CONF_QUERIES):
+        name = query.get(CONF_NAME)
+        query_str = query.get(CONF_QUERY)
+        unit = query.get(CONF_UNIT_OF_MEASUREMENT)
+        value_template = query.get(CONF_VALUE_TEMPLATE)
+        column_name = query.get(CONF_COLUMN_NAME)
+
+        if value_template is not None:
+            value_template.hass = hass
+
+        sensor = SQLSensor(
+            name, sessionmaker, query_str, column_name, unit, value_template
+            )
+        queries.append(sensor)
+
+    add_devices(queries, True)
+
+
+class SQLSensor(Entity):
+    """An SQL sensor."""
+
+    def __init__(self, name, sessmaker, query, column, unit, value_template):
+        """Initialize SQL sensor."""
+        self._name = name
+        if "LIMIT" in query:
+            self._query = query
+        else:
+            self._query = query.replace(";", " LIMIT 1;")
+        self._unit_of_measurement = unit
+        self._template = value_template
+        self._column_name = column
+        self.sessionmaker = sessmaker
+        self._state = None
+        self._attributes = None
+
+    @property
+    def name(self):
+        """Return the name of the query."""
+        return self._name
+
+    @property
+    def state(self):
+        """Return the query's current state."""
+        return self._state
+
+    @property
+    def unit_of_measurement(self):
+        """Return the unit of measurement."""
+        return self._unit_of_measurement
+
+    @property
+    def device_state_attributes(self):
+        """Return the state attributes."""
+        return self._attributes
+
+    def update(self):
+        """Retrieve sensor data from the query."""
+        import sqlalchemy
+        try:
+            sess = self.sessionmaker()
+            result = sess.execute(self._query)
+        except sqlalchemy.exc.SQLAlchemyError as err:
+            _LOGGER.error("Error executing query %s: %s", self._query, err)
+            return
+
+        for res in result:
+            _LOGGER.debug(res.items())
+            data = res[self._column_name]
+            self._attributes = {k: str(v) for k, v in res.items()}
+
+        if data is None:
+            _LOGGER.error("%s returned no results", self._query)
+            return False
+
+        if self._template is not None:
+            self._state = self._template.async_render_with_possible_json_value(
+                data, None)
+        else:
+            self._state = data
+
+        sess.close()
diff --git a/requirements_all.txt b/requirements_all.txt
index 79d87b2d9e5cd67e642a2854f283da54f25e20e4..149bf6d7154e52f7e12d337939c6593638fde566 100644
--- a/requirements_all.txt
+++ b/requirements_all.txt
@@ -1127,6 +1127,7 @@ speedtest-cli==1.0.7
 
 # homeassistant.components.recorder
 # homeassistant.scripts.db_migrator
+# homeassistant.components.sensor.sql
 sqlalchemy==1.2.2
 
 # homeassistant.components.statsd
diff --git a/requirements_test_all.txt b/requirements_test_all.txt
index f4a4e09b1248d739916594a48c722cac8f6dd036..acddad7e9426b27e763e27f4bb10c18da8232db9 100644
--- a/requirements_test_all.txt
+++ b/requirements_test_all.txt
@@ -169,6 +169,7 @@ somecomfort==0.5.0
 
 # homeassistant.components.recorder
 # homeassistant.scripts.db_migrator
+# homeassistant.components.sensor.sql
 sqlalchemy==1.2.2
 
 # homeassistant.components.statsd
diff --git a/tests/components/sensor/test_sql.py b/tests/components/sensor/test_sql.py
new file mode 100644
index 0000000000000000000000000000000000000000..ebf2d749e67b53c7daccfe85452ec1cdaa4f7aee
--- /dev/null
+++ b/tests/components/sensor/test_sql.py
@@ -0,0 +1,37 @@
+"""The test for the sql sensor platform."""
+import unittest
+
+from homeassistant.setup import setup_component
+
+from tests.common import get_test_home_assistant
+
+
+class TestSQLSensor(unittest.TestCase):
+    """Test the SQL sensor."""
+
+    def setUp(self):
+        """Set up things to be run when tests are started."""
+        self.hass = get_test_home_assistant()
+
+    def teardown_method(self, method):
+        """Stop everything that was started."""
+        self.hass.stop()
+
+    def test_query(self):
+        """Test the SQL sensor."""
+        config = {
+            'sensor': {
+                'platform': 'sql',
+                'db_url': 'sqlite://',
+                'queries': [{
+                    'name': 'count_tables',
+                    'query': 'SELECT count(*) value FROM sqlite_master;',
+                    'column': 'value',
+                }]
+            }
+        }
+
+        assert setup_component(self.hass, 'sensor', config)
+
+        state = self.hass.states.get('sensor.count_tables')
+        self.assertEqual(state.state, '0')